核心是预编译+批提交+连接参数优化协同生效;必须配置rewritebatchedstatements=true使驱动合并多条insert为单条多值语句,复用preparedstatement实例、批次大小500–2000、关闭自动提交并手动分批commit。

Java JDBC 批处理导入大数据量,核心是减少数据库交互次数、降低解析开销、控制内存与事务边界。不是“堆数据就快”,而是靠预编译 + 批提交 + 连接参数优化协同生效。
关键配置:MySQL连接必须加 rewriteBatchedStatements=true
这是 MySQL 驱动特有的批量优化开关,不加它,addBatch() 只是把多条 INSERT 分别发过去;加了之后,驱动会自动合并成一条多值语句(如 INSERT INTO t VALUES (?,?),(?,?),(?,?)),性能可提升 3–10 倍。
- URL 示例:jdbc:mysql://localhost:3306/db?useSSL=false&rewriteBatchedStatements=true&useServerPrepStmts=false&characterEncoding=UTF-8
- useServerPrepStmts=false 必须关闭,否则 rewriteBatchedStatements 不生效
- 仅对 INSERT 有效,UPDATE/DELETE 不支持该合并
PreparedStatement 复用 + 合理批次大小
每条记录都 new PreparedStatement 是严重错误——预编译失效、GC 压力大、连接资源浪费。必须复用同一个实例,并按固定大小分批执行。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- PreparedStatement 创建在循环外,setXXX 和 addBatch 在循环内
- 批次大小建议设为 500–2000:太小(如 100)起不到合并效果;太大(如 10000)易触发 OOM 或锁等待
- 每满一批就 executeBatch(),并调用 clearBatch() 清空缓存
- 循环结束后,别忘了处理剩余未满批的数据
手动事务控制:关自动提交 + 定期 commit
默认每 executeBatch() 都隐式提交,日志写入和 I/O 开销极大。应关闭自动提交,把多个批次包进一个事务,但也不能让事务过大(如百万条一 commit),否则可能锁表或拖慢回滚。
- 开头调用 conn.setAutoCommit(false)
- 推荐每 1000–5000 条执行一次 executeBatch() + commit()
- 异常时及时 rollback(),避免脏数据残留
- 最后 commit() 一次收尾,再恢复 setAutoCommit(true)(可选)
其他实用细节
这些点不起眼,但实际压测中常成为瓶颈:
- 避免在循环里拼接 SQL 字符串(如 "INSERT ... '"+name+"'"),有 SQL 注入风险,且无法利用预编译
- 使用 try-with-resources 或 finally 确保 Connection/PreparedStatement 正确关闭
- 大批量场景下,LOAD DATA INFILE 比 JDBC 快 5–10 倍,但需文件落库服务器、权限开放,适合离线导入
- Oracle/PostgreSQL 用户注意:前者推荐 setExecuteBatch() 流式提交;后者更优解是 CopyManager 协议
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










