Java中JDBC大批量分页全量同步的核心是用主键/自增ID游标分页(WHERE id > ? ORDER BY id LIMIT ?),避免OFFSET深翻,配合索引、合理pageSize(2000–5000)、fetchSize设置、断点续传(sync_checkpoint表)及目标端批处理(addBatch/executeBatch)实现高效可靠同步。

Java 中用 JDBC 做大批量数据的分页全量同步,核心是“不加载全量、不单条处理、不断点丢失”,重点在可控分批 + 状态可追溯 + 写入高效。
用主键/自增ID做游标分页,避免 OFFSET 深翻
不要用 LIMIT (page-1)*size, size 这类基于偏移量的分页——数据量大时,OFFSET 越大越慢,数据库要跳过大量行。推荐基于单调递增字段(如 id、create_time)做游标分页:
- 每次查 WHERE id > ? ORDER BY id LIMIT ?,把上一批最大 id 作为下一批起点
- 首次查询用 SELECT MIN(id) FROM table 获取起始点
- 配合索引(id 必须有主键或唯一索引),确保排序和范围扫描高效
- 若无合适数字主键,可用时间字段 + 唯一业务键组合,但需注意时钟回拨或重复问题
控制分页大小与内存占用平衡
pageSize 不是越大越好,也不是越小越稳,要结合实际资源调优:
- 典型值选 2000–5000 行:太小导致网络往返频繁;太大易触发 GC 或 OOM
- JDBC 层设置 statement.setFetchSize(pageSize),提示驱动按需拉取,减少内存缓冲
- 避免把整页结果一次性转成 List
- 对 Oracle 等数据库,可用 ROWNUM 包裹实现类似效果,但注意子查询写法顺序
同步过程带状态记录与断点续传能力
全量同步耗时长,必须支持中断后从断点继续,不能重头再来:
- 每次处理完一页后,把当前批次的 maxId 或 endTime 写入一张轻量控制表(如 sync_checkpoint)
- 启动时先查该表,恢复 lastId;失败时也以该值为起点重试
- 可搭配 Redis 存临时 checkpoint,提升读写速度,但需注意持久化与一致性
- 对关键业务,建议每 N 批加一次校验(如本批行数、sum(id) 或 checksum),防静默错漏
目标端批量写入要启用 JDBC 批处理
源端分页只是第一步,目标端写入效率往往才是瓶颈:
- 使用 PreparedStatement.addBatch() + executeBatch(),禁用自动提交
- 配置连接池参数,如 HikariCP 的 allowMultiQueries=true(MySQL)或 rewriteBatchedStatements=true(大幅优化 MySQL 批量性能)
- Doris 场景优先走 Stream Load,JDBC 仅作兜底;PostgreSQL 可用 COPY 协议;Oracle 可用 Array DML
- 写入前做必要转换(空值处理、类型映射、字段截断),避免因单条失败导致整批回滚
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











