这是我转载的,但是我亲测了,好用!我的问题这个方法解决了!!
昨天研究了一下mysql的批处理,最初发现很慢
代码如下:
- package
- import
- publicclass
- publicstaticvoid
- try
- "com.mysql.jdbc.Driver"
- "jdbc:mysql://127.0.0.1:3306/test_deletable?useUnicode=true&characterEncoding=UTF-8"
- "mysql""mysql"
- int50000
- int5000000
- false);//设置自动提交为false
- "===================="
- forlong1
- 1//设置第一个参数的值为i
- //将该条记录添加到批处理中
- if0
- //执行批处理
- //提交
- ":添加"+batchSize+"条"
- if10
- +batchSize++(t2-t1)/1000+"秒"
- catch
很明显,1万条数据,需要执行243秒。
这个代码的性能很低,首先排除该表的复杂性(该表只有两个字段,id为自增主键),二、排除逻辑复杂性(从代码可以看出,这段代码只是简单的把i值赋给id)
后来又调整了很多参数,但都没有找到根本原因,执行时间会有稍微提高或者没什么变化。
最后,添加参数rewriteBatchedStatements=true
即:
- "jdbc:mysql://127.0.0.1:3306/test_deletable?rewriteBatchedStatements=true&useUnicode=true&characterEncoding=UTF-8"
- "mysql""mysql"
执行时间提高100倍以上
后续修改批处理大小,得到执行时间不一样。
可以看出来,批处理大小的设置,也是影响执行时间的一个重要原因,但并不是设置的越大越好,或者越小越好。
下面介绍一下rewriteBatchedStatements
MySql的JDBC连接的url中要加rewriteBatchedStatements参数,并保证5.1.13以上版本的驱动,才能实现高性能的批量插入。
MySQL Jdbc驱动在默认情况下会无视executeBatch()语句,把我们期望批量执行的一组sql语句拆散,一条一条地发给MySQL数据库,直接造成较低的性能。
只有把rewriteBatchedStatements参数置为true, 驱动才会帮你批量执行SQL (jdbc:mysql://ip:port/db?rewriteBatchedStatements=true)。
实验记录:未打开rewriteBatchedStatements时
未打开rewriteBatchedStatements时,根据wireshark嗅探出的mysql报文可以看出,
也就是说,batchXXX()的确不起作用
实验记录:打开了rewriteBatchedStatements后
打开rewriteBatchedStatements后,根据wireshark嗅探出的mysql报文可以看出
对delete和update,驱动所做的事就是把多条sql语句累积起来再一次性发出去;而对于insert,驱动则会把多条sql语句重写成一条风格很酷的sql语句,然后再发出去。 官方文档说,这种insert写法可以提高性能(”This is considerably faster (many times faster in some cases) than using separate single-row INSERT statements”)
一个注意事项
需要注意的是,即使rewriteBatchedStatements=true, batchDelete()和batchUpdate()也不一定会走批量:。所以,如果你想验证rewriteBatchedStatements在你的系统里是否已经生效,记得要使用较大的batch.
文章来源: MySQL批量插入处理之提高速度