之前测试MySQL批量插入,发现慢的离谱,找了下原因,竟然是少了个参数,rewriteBatchedStatements=true。昨天《PostgreSQL vs MySQL - 30倍性能差异》这个原因也找到了,汗颜。
rewriteBatchedStatements介绍
rewriteBatchedStatements=true 是MySQL JDBC驱动程序中的一个连接属性,用于启用批量重写功能。它可以在执行批量插入操作时提高性能。
默认情况下,在JDBC中使用批量插入时,每个插入语句都会作为单独的请求发送到数据库服务器。但是,将 rewriteBatchedStatements 设置为 true 时,驱动程序会对批量插入语句进行重写和优化,将多个插入语句合并成一个批量语句,然后一次性发送给数据库服务器。
通过启用批量重写功能,可以减少与数据库服务器之间的通信开销和网络往返时间。此外,将多个插入语句合并为一个批量语句还可以减少数据库服务器上的查询计划优化和日志记录操作,从而提高整体性能。
需要注意的是,启用 rewriteBatchedStatements=true 并不总是能够带来显著的性能改进。它的效果取决于多个因素,包括数据量、网络延迟、数据库和系统配置等。在某些情况下,尤其是需要大量数据插入的场景,启用该选项可以明显提升性能。然而,在某些情况下,可能不会看到明显的性能改进或甚至性能下降。
连接参数修改
在连接之后加上rewriteBatchedStatements=true,如下:
String url = "jdbc:mysql://localhost/mydatabase?rewriteBatchedStatements=true";
测试结果
先插入少量数据:10万条。下述结果,耗时毫秒级被我省略了,所以针对10万的数据量插入,看不出大的差异。
每批数量 | 耗时 (第一轮) | 耗时 | 耗时 | 耗时 (第n轮) | 平均耗时 | 每秒写入速度 |
100 | 6s | 6s | 6s | …… | 6s | ≈16666/s |
500 | 4s | 4s | 4s | …… | 4s | ≈25000/s |
1000 | 4s | 4s | 4s | …… | 4s | ≈25000/s |
3000 | 4s | 4s | 4s | …… | 4s | ≈25000/s |
5000 | 4s | 4s | 4s | …… | 4s | ≈25000/s |
10000 | 4s | 4s | 4s | …… | 4s | ≈25000/s |
这个测试结果和昨天测试的PostgreSQL相当(符合预期)。
接下来测试一下1000w数据的耗时,并对比一下PostgreSQL的性能(代码均复用上篇)。
测试结果
每批数量 | MySQL | PostgreSQL | 每秒写入速度 | 每秒写入速度 |
100 | 8m 43s | 3m 36s | ≈19120 | ≈46296 |
500 | 5m 26s | 3m 37s | ≈30674 | ≈46082 |
1000 | 4m 59s | 3m 36s | ≈33444 | ≈46296 |
3000 | 4m 42s | 3m 35s | ≈35460 | ≈46511 |
5000 | 4m 41s | 3m 36s | ≈35587 | ≈46296 |
10000 | 4m 35s | 3m 38s | ≈36363 | ≈45871 |
20000 | 4m 36s | 3m 42s | ≈36231 | ≈45045 |
结论
- MySQL 批量插入时批量不同性能差异较大,PostgreSQL相对稳定。
- 相同配置下PostgreSQL插入性能略具上风。
- MySQL批量插入一定不能忘了加 rewriteBatchedStatements=true ,不然就像之前测试,就是搞笑的
本数据只是个人测试,仅供参考,不同环境、场景、配置等因素下,结论可能都不一致,大家可根据实际情况进行测试。