SQLite插入场景下使用addBatch/executeBatch比顺序执行查询更有优势吗?
核心结论
你最初的每次调用都新建连接的update方法,和批量操作比性能差很多,因为每次新建数据库连接、预编译SQL的开销极高,这部分开销批量操作可以完全省掉。你后续测试出现批量操作更慢的情况,是SQLite驱动特性、事务配置、参数未优化共同导致的,不是批量操作本身没有优势。
测试结果反常的原因
- 驱动默认没有做批量SQL合并
绝大多数JDBC驱动(包括SQLite的常用实现)默认不会把addBatch的多条插入合并为单条多值的INSERT语句,executeBatch本质还是把攒的SQL逐条发给数据库执行,反而多了缓存20000组参数的序列化、内存开销,自然比执行一条处理一条的updateCommon慢。 - 事务提交的影响
JDBC连接默认开启自动提交,你用updateCommon每次调用executeUpdate都会触发一次事务提交,SQLite作为文件型数据库,事务提交需要刷磁盘,按理说这部分开销应该远高于批量操作一次提交的开销。你的测试结果反过来,大概率是两个测试的事务配置不一致,或者updateCommon的测试代码没有正确释放资源,触发了连接池的隐式事务合并优化。 - 单次批量数据量过大
你一次性攒了20000条数据才执行executeBatch,大量参数缓存在内存里,不仅占内存,参数序列化、校验的额外开销也会被放大,抵消了批量操作的优势。
批量操作的实际优势场景
只要做对以下配置,批量操作的性能会远高于单次执行:
- 开启驱动批量重写参数:在SQLite的JDBC连接串里加上
rewriteBatchedStatements=true,驱动会自动把批量插入合并为INSERT OR REPLACE INTO Table1 (STRINGNAME, VALUE) VALUES (?,?), (?,?), ...的单条语句,一次执行就能完成所有插入,性能可以提升几倍到几十倍。 - 统一事务控制:手动关闭连接的自动提交,所有操作完成后一次性commit,不管是单次执行还是批量执行,都能省掉多次事务刷盘的开销,这时候批量操作的优势会更明显。
- 分批提交:不要一次性攒几万条再执行批量,建议每500~1000条执行一次
executeBatch,平衡内存开销和执行效率。
补充说明
如果你对比的是复用同一个连接、同一个PreparedStatement、相同事务配置的单次执行和批量执行,在开启了SQL重写的前提下,批量执行的性能至少是单次执行的3~10倍,不会出现你测试里的反常规情况。
内容的提问来源于stack exchange,提问作者mtm
相关产品推荐
相关产品推荐

