开发者社区> 长源> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

MySQL JDBC 的 BATCH 执行和 rewriteBatchedStatements 参数

简介: 本来以为这是一个已解决的问题,但是发现有同学不知道,所以写一下。 经常使用 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时报由于找不到VCRUNTIME140_1.dll,无法继续执行代码。重新安装程序可能会解决此问题错误
安装MySQL时报由于找不到VCRUNTIME140_1.dll,无法继续执行代码。重新安装程序可能会解决此问题错误
20 0
【Linux】【开发环境】【RHEL】开发环境搭建系列之七——安装基础MySQL环境
【Linux】【开发环境】【RHEL】开发环境搭建系列之七——安装基础MySQL环境
9 0
Docker安装Mysql,Redis,ElasticSearch
Docker安装Mysql,Redis,ElasticSearch
19 0
04_mysql安装 Docker安装mysql
简单实用Docker安装部署mysql github:https://github.com/qq153916230/study.git
12 0
MySQL_01:MySQL的安装、下载、卸载、配置、登录
MySQL_01:MySQL的安装、下载、卸载、配置、登录
25 0
Centos安装MySQL详细步骤
Centos安装MySQL详细步骤
36 0
Docker安装MySQL|学习笔记
快速学习Docker安装MySQL
26 0
MySQL 安装和基本操作| 学习笔记
快速学习 MySQL 安装和基本操作
65 0
系统已有MYSQL环境,如何安装宝塔面板
最近一直想搞一个在线博客网站,把代码部署到服务器。 下载己经下载了宝塔的.exe文件,安装提示系统已经存在MYSQL环境,请用纯净系统安装。
81 0
2022最新mysql安装与配置教程(简单易懂,图文解释)
2022最新mysql安装与配置教程(简单易懂,图文解释)
61 0
+关注
长源
2010 年加入阿里中间件,专注于 TDDL/DRDS 产品研发。负责过多个大型项目的分布式数据库设计, 对分布式场景的事务处理及复杂查询优化具有丰富经验。
文章
问答
文章排行榜
最热
最新
相关电子书
更多
MySQL 5.7让优化更轻松
立即下载
好的 MySQL 兼容可以做到什么程度
立即下载
PostgresChina2018_张启程_为什么我们抛弃MongoDB和MySQL,选择PgSQL
立即下载