MySQL JDBC 的 BATCH 执行和 rewriteBatchedStatements 参数

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 本来以为这是一个已解决的问题,但是发现有同学不知道,所以写一下。 经常使用 MySQL 的同学可能知道,默认情况下 MySQL JDBC 驱动是不支持 BATCH 的: ```Java try (Connection conn = dataSource.getConnection(); Statement stmt = conn.createStatement()) {

本来以为这是一个已解决的问题,但是发现有同学不知道,所以写一下。

经常使用 MySQL 的同学可能知道,默认情况下 MySQL JDBC 驱动是不支持 BATCH 的:

try (Connection conn = dataSource.getConnection();
    Statement stmt = conn.createStatement()) {
    stmt.addBatch("INSERT INTO test (id, name, number, gmt) VALUES (1, 'Adam',  100, NOW())");
    stmt.addBatch("INSERT INTO test (id, name, number, gmt) VALUES (2, 'Brown', 200, NOW())");
    stmt.addBatch("INSERT INTO test (id, name, number, gmt) VALUES (3, 'Clair', 300, NOW())");
    ...
    stmt.executeBatch();  
} catch (SQLException e) {
    e.printStackTrace();
}

在真正执行的时候,MySQL JDBC 驱动仍然是把三条语句顺序发给 MySQL 执行。这样其实就是没有 BATCH —— 既没有降低网络通讯的成本,也不能在服务端批量执行。

因此 MySQL JDBC 提供了一个参数 rewriteBatchedStatements 改善这个行为。设置 rewriteBatchedStatements=true 以后,MySQL JDBC 会以两种方式重写批量提交的 SQL 语句,实现一次送达,批量执行的目标:

1) INSERT / INSERT ON DUPLICATE KEY UPDATE / REPLACE (5.1.37+) 会重写成 Multi-Values 的形式,但是限制是必须是使用 PreparedStatement 批量执行的语句。这个限制很容易理解,因为 Statement 提供的 BATCH 接口不能保证批量执行的语句全部是相同类型。

INSERT INTO test (id, name, number, gmt) VALUES 
    (1, 'Adam',  100, NOW()), 
    (2, 'Brown', 200, NOW()), 
    (3, 'Clair', 300, NOW()), 
    ... 
[ ON DUPLICATE KEY UPDATE 
    name   = VALUES(name), 
    number = VALUES(number), 
    gmt    = VALUES(gmt), 
    ... ]

2)重写成 Multi-Query 的形式,简单来说就是在 SQL 间加入分号,合并成一条多语句发给 MySQL 服务端。所有不符合 1) 的都会重写成多语句,但是多语句在 MySQL 服务端的执行效率较低:

UPDATE test SET name = 'Adam',  number = 100, gmt = NOW() WHERE id = 1;
UPDATE test SET name = 'Brown', number = 200, gmt = NOW() WHERE id = 2;
UPDATE test SET name = 'Clair', number = 300, gmt = NOW() WHERE id = 3;
...

特别要注意的一点是:MySQL JDBC 版本在 5.1.37 以下不支持 REPLACE 的 Multi-Values 重写。因此批量 REPLACE 会使用多语句的方式发送到 MySQL 服务端,会观察到 REPLACE 的批量写入效率严重低于 INSERT 和 INSERT ON DUPLICATE KEY UPDATE。

有关 MySQL BATCH 的主要问题就这些,谢谢,做了一些微小的工作。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
15天前
|
SQL 存储 关系型数据库
MySQL进阶突击系列(01)一条简单SQL搞懂MySQL架构原理 | 含实用命令参数集
本文从MySQL的架构原理出发,详细介绍其SQL查询的全过程,涵盖客户端发起SQL查询、服务端SQL接口、解析器、优化器、存储引擎及日志数据等内容。同时提供了MySQL常用的管理命令参数集,帮助读者深入了解MySQL的技术细节和优化方法。
|
26天前
|
关系型数据库 MySQL 数据库
【赵渝强老师】MySQL的参数文件
MySQL启动时会读取配置文件my.cnf来确定数据库文件位置及初始化参数。该文件分为Server和Client两部分,包含动态与静态参数。动态参数可在运行中通过命令修改,而静态参数需修改my.cnf并重启服务生效。文中还提供了相关代码示例和视频教程。
|
1月前
|
缓存 监控 关系型数据库
如何根据监控结果调整 MySQL 数据库的参数以提高性能?
【10月更文挑战第28天】根据MySQL数据库的监控结果来调整参数以提高性能,需要综合考虑多个方面的因素
78 1
|
20天前
|
存储 Java 数据库连接
南大通用 GBase 8s JDBC字符集参数详解
本文详细介绍了南大通用GBase 8s V8.8 数据中四个关键的JDBC字符集参数:CLIENT_LOCALE、DB_LOCALE、NEWCODESET和NEWLOCALE,涵盖它们的功能、配置方法及其在数据库操作中的作用,旨在帮助开发者和数据库管理员提升数据处理的效率与准确性。
|
2月前
|
Java 关系型数据库 MySQL
mysql5.7 jdbc驱动
遵循上述步骤,即可在Java项目中高效地集成MySQL 5.7 JDBC驱动,实现数据库的访问与管理。
382 1
|
2月前
|
SQL 分布式计算 关系型数据库
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
97 0
|
2月前
|
SQL 分布式计算 关系型数据库
Hadoop-23 Sqoop 数据MySQL到HDFS(部分) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-23 Sqoop 数据MySQL到HDFS(部分) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
43 0
|
2月前
|
SQL 分布式计算 关系型数据库
Hadoop-22 Sqoop 数据MySQL到HDFS(全量) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-22 Sqoop 数据MySQL到HDFS(全量) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
56 0
|
4月前
|
SQL druid Java
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)(下)
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)
60 3
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)(下)
|
4月前
|
SQL Java 关系型数据库
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)(上)
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)
170 3
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)(上)