写 MySQL 用 JdbcTemplate、JdbcClient 还是 JPA 更快?批量写入到底能快多少?rewriteBatchedStatements 与主键策略有什么影响?这篇在同一台机器上把九种写法各跑两轮,波动大的地方照实写出来。
1 JdbcTemplate.update 逐行,每行自动提交(n=2000):两轮 231 ms / 2119 ms,即 8652 / 944 行/秒 2 JdbcClient.sql().params().update() 逐行,每行自动提交(n=2000):两轮 260 ms / 1230 ms,即 7679 / 1626 行/秒 3 JPA repository.save 逐行,每次 save 一个事务(IDENTITY)(n=2000):两轮 566 ms / 818 ms,即 3531 / 2445 行/秒 4 JdbcTemplate.update 逐行,同一个事务(n=20000):两轮 855 ms / 2630 ms,即 23396 / 7604 行/秒 5 JdbcClient 逐行,同一个事务(n=20000):两轮 818 ms / 983 ms,即 24443 / 20336 行/秒 6 JPA save 逐行,同一个事务(IDENTITY)(n=20000):两轮 1083 ms / 1178 ms,即 18468 / 16979 行/秒 7 JdbcTemplate.batchUpdate(每批 1000),同一个事务(n=20000):两轮 721 ms / 790 ms,即 27758 / 25332 行/秒 8 JPA saveAll(IDENTITY,hibernate.jdbc.batch_size=1000),同一个事务(n=20000):两轮 994 ms / 1000 ms,即 20127 / 19992 行/秒 9 JPA saveAll(AUTO 序列,hibernate.jdbc.batch_size=1000),同一个事务(n=20000):两轮 1538 ms / 964 ms,即 13006 / 20751 行/秒
批量写入只比逐行快一点;自动提交逐行波动极大;JdbcTemplate 与 JdbcClient 无法区分。
1 JdbcTemplate.update 逐行,每行自动提交(n=2000):两轮 218 ms / 237 ms,即 9178 / 8450 行/秒 2 JdbcClient.sql().params().update() 逐行,每行自动提交(n=2000):两轮 282 ms / 206 ms,即 7100 / 9723 行/秒 3 JPA repository.save 逐行,每次 save 一个事务(IDENTITY)(n=2000):两轮 845 ms / 448 ms,即 2367 / 4462 行/秒 4 JdbcTemplate.update 逐行,同一个事务(n=20000):两轮 832 ms / 821 ms,即 24043 / 24375 行/秒 5 JdbcClient 逐行,同一个事务(n=20000):两轮 950 ms / 930 ms,即 21054 / 21496 行/秒 6 JPA save 逐行,同一个事务(IDENTITY)(n=20000):两轮 1103 ms / 1036 ms,即 18137 / 19302 行/秒 7 JdbcTemplate.batchUpdate(每批 1000),同一个事务(n=20000):两轮 78 ms / 82 ms,即 257010 / 242633 行/秒 8 JPA saveAll(IDENTITY,hibernate.jdbc.batch_size=1000),同一个事务(n=20000):两轮 892 ms / 947 ms,即 22421 / 21120 行/秒 9 JPA saveAll(AUTO 序列,hibernate.jdbc.batch_size=1000),同一个事务(n=20000):两轮 233 ms / 306 ms,即 85714 / 65377 行/秒
batchUpdate 与 AUTO 主键的 saveAll 大幅加速;IDENTITY 主键仍不批量。