有人说MySql的JDBC驱动,不是真正支持批量操作的,就算你在代码中调用了批量操作的方法,MySql的JDBC驱动也是按照一般操作来处理的。
但其实并非如此,Mysql 是有特殊的方式优化整个batch insert 结果的。
可不可以先假设 batch 的方式与非batch一样,每一条insrt语句事实上均是单独发往服务器的呢?
浏览下源代码吧。
好多兄弟都描述了源代码,直接从那几个类入手吧,事实上关键的类是这个 com.mysql.jdbc.PreparedStatement
先看了其中的 addBatch 方法,没有任何问题,只是将语句添加进入一个 List 中保存。
那么 executeBatch 呢?
再贴一下吧, 关键看其中的这部分,顺带说一下, 这个mysql-jdbcdriver的源代码是 5.1.13的
try { clearWarnings(); if (!this.batchHasPlainStatements && this.connection.getRewriteBatchedStatements()) { if (canRewriteAsMultiValueInsertAtSqlLevel()) { return executeBatchedInserts(batchTimeout); //执行路径之一 } if (this.connection.versionMeetsMinimum(4, 1, 0) && !this.batchHasPlainStatements && this.batchedArgs != null && this.batchedArgs.size() > 3 /* cost of option setting rt-wise */) { return executePreparedBatchAsMultiStatement(batchTimeout); //执行路径之二 } } return executeBatchSerially(batchTimeout); //执行路径之三 } finally { clearBatch(); }
String connectionUrl="jdbc:mysql://192.168.1.100:3306/test?rewriteBatchedStatements=true";
insert into t_user(id,uname) values(1, '1'), (2,'2'), (3, '3') ....
MySql JDBC 驱动版本 | 结果 |
5.0.8 | 没有提高 18秒 |
5.1.7 | 没有提高 18秒 |
5.1.13 | 有提高 1.6秒 |
所以Mysql的批量操作一定要加上MySql连接的url中要加rewriteBatchedStatements参数设为true