jdbc批处理插入海量数据的核心是减少交互次数、避免sql重复编译、合理控制事务粒度;需用preparedstatement预编译,关闭自动提交并手动分批commit,启用数据库特有优化参数(如mysql的rewritebatchedstatements=true),批大小建议500–2000条。

用JDBC批处理插入海量数据,核心是减少数据库交互次数、避免重复SQL编译、合理控制事务粒度。单条插入百万数据可能耗时几分钟甚至更久,而正确使用批处理通常可压缩到十几秒内。
开启批处理并配合预编译语句
必须使用 PreparedStatement 而非 Statement,因为前者支持参数化、预编译,避免每次执行都解析SQL。关键步骤包括:
- 调用
connection.prepareStatement(sql)创建预编译语句 - 循环中设置参数后调用
pstmt.addBatch()累积操作 - 每累积一定数量(如500或1000条)就调用
pstmt.executeBatch() - 执行后立即调用
pstmt.clearBatch()防止内存持续增长
关闭自动提交并手动管理事务
默认的自动提交会让每批执行都触发一次事务提交,开销极大。应显式关闭并按批次统一提交:
- 在获取连接后执行
conn.setAutoCommit(false) - 在每批
executeBatch()后调用conn.commit() - 全部完成后恢复自动提交:
conn.setAutoCommit(true) - 发生异常时需回滚:
conn.rollback(),再关闭资源
适配数据库特性提升吞吐量
不同数据库有专属优化参数,不启用可能让批处理效果打折:
-
MySQL:JDBC URL 中添加
?rewriteBatchedStatements=true,可将多条 INSERT 合并为一条INSERT ... VALUES (...),(...),...,性能提升常达3–5倍 -
PostgreSQL:启用
reWriteBatchInserts=true并配合useServerPrepStmts=true -
SQL Server:推荐结合表值参数(TVP),但若只用JDBC,确保驱动版本较新,并开启
sendStringParametersAsUnicode=false减少字符转换开销
控制批大小与资源平衡
批数量不是越大越好,需兼顾内存、事务日志和错误恢复能力:
- 建议起始值设为 500–2000 条/批;超过5000条易引发
OutOfMemoryError或事务日志膨胀 - 若数据中存在主键冲突等可预期错误,小批次(如200条)更利于定位失败记录
- 配合连接池(如 HikariCP)使用,避免频繁创建连接;连接池最小空闲数建议 ≥2,防止批量时连接被其他请求抢占











