高效迁移百万级数据需绕开低效路径:优先用mysql的load data local infile批量导入csv;次选jdbc批量插入并优化参数、批次大小和事务提交;跨库迁移须读写分离、分页拉取与队列解耦;全程注重断点续传、数据校验与日志追踪。

处理百万级数据的高效迁移,核心不在“怎么写SQL”,而在于绕开低效路径、分层控制资源、让数据库和Java各干擅长的事。直接逐条INSERT或单一大事务,基本等于主动放弃性能。
优先走数据库原生批量加载通道
如果目标库是MySQL,且数据源可转为结构化文本(如CSV),LOAD DATA LOCAL INFILE 是目前最快路径。它跳过SQL解析、连接池调度、JDBC封装等全部Java层开销,由MySQL服务端直接读文件入库。实测100万行通常在30秒内完成。关键点:
- Excel先用EasyExcel流式转CSV,避免内存溢出
- JDBC URL需启用
allowLoadLocalInfile=true,MySQL服务端配置local_infile=ON - 导入前禁用唯一索引和外键约束,导入后再重建,提速明显
Java端批量插入必须配合底层优化
当无法使用LOAD DATA(比如跨数据库、需校验转换),JDBC批量插入是主力方案,但默认行为极慢。必须做三件事:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 开启JDBC参数:
rewriteBatchedStatements=true(MySQL)或useServerPrepStmts=false(PostgreSQL),让驱动把多条INSERT合并为一条语句发送 - 每批控制在1000–5000条,太大易触发GC或超时,太小则网络往返开销占比高
- 关闭自动提交,手动
connection.commit(),但别把100万包进一个事务——按批次提交,兼顾速度与回滚粒度
跨库迁移要拆开“读”和“写”两层压力
Oracle→MySQL、SQL Server→PostgreSQL这类场景,不能让一个线程既查又插。正确做法是:
- 用独立线程/连接从源库分页拉取(推荐游标分页或基于主键范围查询,避免
OFFSET) - 拉取结果存入内存队列(如
BlockingQueue)或临时文件,解耦读写速率差异 - 另起多个写线程,从队列消费数据,按批次批量插入目标库
- 源库查询设置
fetchSize,目标库连接池调大maxActive,防止连接争抢
别忽视数据一致性与失败恢复
百万级迁移不是“跑完就完”,中途失败必须能续跑:
- 记录每个批次的起始主键值或时间戳,失败后从断点继续,而非重头再来
- 对关键字段加校验(如MD5摘要比对源目标行数、SUM校验金额字段),导完立刻验证
- 日志按批次输出,包含耗时、条数、异常堆栈,方便定位哪一批卡住
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










