有人说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();
}
其实最终,executeBatch 的执行路径有三种可能。代码中我已标出来
代码不算太复杂,但是有一个参数能帮助我们更快的确定mysql的batch工作机制,那就是
mysql jdbc driver 的connection url, 其中有一个参数是: rewriteBatchedStatements
完整的参数参考看这里:http://ftp.ntu.edu.tw/ftp/pub/MySQL/doc/refman/5.1/en/connector-j-reference-configuration-properties.html
rewriteBatchedStatements 参数默认为false, 需要手工设置为true,设置方式大概像这样:
String connectionUrl="jdbc:mysql://192.168.1.100:3306/test?rewriteBatchedStatements=true";
默认时候,rewriteBatchedStatements=false时,执行路径会跳到 executeBatchSerially,此方法内部将语句一条条发送,与非batch处理简直一样,所以慢,就在这里了。
当设为 true时,会执行executeBatchedInserts方法,事实上mysql支持这样的插入语句
insert into t_user(id,uname) values(1, '1'), (2,'2'), (3, '3') ....
针对rewriteBatchedStatements=true 参数我做了测试,我加了这个参数,做同们的插入10万条记录测试:
我的mysql 安装的虚拟机上,所以慢一些。
MySql JDBC 驱动版本 |
结果 |
5.0.8 |
没有提高 18秒 |
5.1.7 |
没有提高 18秒 |
5.1.13 |
有提高 1.6秒 |
所以Mysql的批量操作一定要加上MySql连接的url中要加rewriteBatchedStatements参数设为true
分享到:
相关推荐
【IT十八掌徐培成】Java基础第23天-03.ppst-addBatch-executeBatch.zip
###批量操作 - Statement批量操作: statement.addBatch(sql1); statement.addBatch(sql2); statement.addBatch(sql3); //执行批量操作 statement.executeBatch(); - PreparedStatement批量操作: ...
【IT十八掌徐培成】Java基础第23天-03.ppst-addBatch-executeBatch - 副本.zip
使用JDBC连接MySQL数据库进行数据插入的时候,特别是大批量数据连续插入(10W+),如何提高效率呢? 在JDBC编程接口中Statement 有两个方法特别值得注意: void addBatch() throws SQLException Adds a set of ...
尽管这样作在Java中没有什么问题,但由于操作都是在数据库之外进行的,因此其他访问数据库的应用软件无法利用对象模式。如果利用Oracle的面向对象的技术,可以通过创建一个新的数据库对象类型在数据库中模仿其数据和...
有时候JDBC运行得不够快,这使得有些程序员使用数据库... 使用批量处理功能涉及下面的两个方法: · addBatch(String) 方法 · executeBatch方法 如果你正在使用Statement 那么addBatch 方法可以接受一个通
《java面试800题(包括java,数据库,前台等,绝对全面)》 Q0027 哪些SQL语句在执行时是自动提交的? 数据定义语言DDL是自动提交的。 Q0028 索引对数据库的影响? 提高查询速度 Q0029 主外键有什么关系? 外键是从...
主要介绍了Hibernate管理Session和批量操作的技巧,包括Hibernate管理Session、批量处理数据等的常用技巧及注意事项,具有一定的参考借鉴价值,需要的朋友可以参考下
单向的一对多的关系,在进行关联关系的操作时,会执行不必要的update语句,所以,一般情况下,我们不会做单向一对多的映射。 inverse="true":让其中一方放弃对关联关系的维护 一般在做双向多对一(一对多)关联关系...
主要介绍了Oracle addBatch()用法实例详解的相关资料,这里提供实例帮助大家掌握理解这部分知识,需要的朋友可以参考下
jdao是一个轻量级的orm工具包,通过简单配置或者连接数据库提供表名它便可以自动生成与数据库表一一对应的dao类,生成的dao类提供了与SQL无关的增删改查的功能。在复杂的查询SQL中,我建议编程人员自己编写高效的SQL...
… sm.executeBatch() 用Statement的好处就是每次可以直接传一个SQL语句进去,不用管那么多。可是在数据量比较大的时候,应该会对效率有影响。不建议使用。 PreparedStatement ps = cn.preparedStatement(sql); { ...
int rows = session.executeBatch(); //执行 b.有参批量更新 String sql = "update bd_deptdoc set dept_code =„aaa‟ where dept_code=?”; SQLParameter param = new SQLParameter(); //构造参数对象 param....
//建立数据库操作 Connection conn=DBConnection.getConn(); Statement sta=null; try { sta=conn.createStatement(); //将自动提交模式转换为手动提交模式 conn.setAutoCommit(false); Iterator<Ticket> ...
//用于对订单项进行操作的预定义语句 ResultSet rs = null; DbUtil dbUtil = null; String sql_order = "insert into tb_order values(null,?,?,?,?,?,null,?)"; try { //事物处理 dbUtil = new ...
100万级数据插入 总结目前网上的spring batchUpdate方法,和jdbc PreparedStatement的addBatch,及insert的2种插入方式引起的效率差别,我的博客中有说明!
stat.addBatch(o.toString()); } stat.executeBatch(); conn.commit(); sign = true; } catch (Exception ex) { conn.rollback(); sign = false; ex.printStackTrace(); } finally { ...
封装mong关联查询api接口,如addBatch()、delete()、exists()、lookUp()等接口 public void delete(Query query , Object obj , String collectionName){ mongoTemplate.remove(query, obj .getClass(), ...
发誓 vows是NodeJS的测试框架。 执照 版权所有2016-2018 Fuzzy.ai 版权2017 AJ乔丹 根据Apache许可版本2.0(“许可”)许可; 除非遵守许可,否则不得使用此文件。 您可以在以下位置获得许可的... addBatch ( { 'Wh