千万级订单数据导出解决方案(解决慢、OOM、锁表)

千万级订单数据导出解决方案(解决慢、OOM、锁表) 目录一、核心问题根源二、最优落地方案生产首选异步 分页流式导出 大文件分片方案架构1. 数据库层优化重中之重1必须加索引避免全表扫描2分页方式主键分页游标分页替代传统 Limit 分页3查询优化防止锁表、长事务2. 应用层流式写入 Excel彻底解决 OOM推荐组件关键代码思路伪代码3. 异步任务解决前端超时、服务阻塞4. 文件存储与分片超大文件优化方式 1文件拆分推荐给运营使用方式 2导出为 CSV大数据量终极方案三、备选方案按场景选用方案 1数据库原生导出运维 / 技术侧快速导出不面向前端MySQL into outfile服务器本地导出方案 2大数据架构数据量持续暴涨亿级数据四、关键避坑点生产必看五、方案选型总结最简落地步骤直接照着做针对日单 1000、总数据千万级的订单表导出场景核心思路分页流式读写、分批落地、异步任务、避免全表加载进内存下面分方案、实操、避坑逐一说明按落地优先级排序。一、核心问题根源直接select * 全表 内存组装Excel千万数据一次性加载 →内存溢出 (OOM)单页查询量大、网络 / IO 串行 →导出超时、速度慢全表查询无索引、长事务 →数据库锁表、影响线上业务二、最优落地方案生产首选异步 分页流式导出 大文件分片方案架构前端触发导出 → 后端创建异步任务→ 数据库游标 / 分页流式读取→ 本地 / 对象存储逐行写入文件 → 完成后推送下载链接 / 消息通知。1. 数据库层优化重中之重1必须加索引避免全表扫描千万级订单表绝对不能无分页、无索引查全表分页唯一条件自增主键 IDorder_id建立主键索引若有时间筛选按日期导出给create_time建普通索引禁止limit 1000000, 1000深分页性能雪崩2分页方式主键分页游标分页替代传统 Limit 分页传统limit offset, size偏移量大时数据库遍历数据极慢改用ID 游标分页最优-- 第一页 select * from order where order_id 0 order by order_id asc limit 1000; -- 下一页用上一页最大ID作为条件 select * from order where order_id #{lastMaxId} order by order_id asc limit 1000;分页步长建议1000~2000 条 / 页平衡 DB 压力与 IO 效率全程order by 主键保证数据不重复、不丢失3查询优化防止锁表、长事务读写分离导出查询走从库完全不影响主库下单、改单业务关闭事务 / 只读事务导出是纯查询不要开启业务事务避免长事务锁行MySQL 配置开启read-only、bulk_insert_buffer_size适当调大net_read_timeout2. 应用层流式写入 Excel彻底解决 OOM核心不把全表数据加载到 JVM 内存读一批、写一批、释放一批推荐组件阿里EasyExcel首选专为大文件导出设计低内存、流式读写原生支持分批写入完全规避 POI OOM 问题禁用原生 POIHSSF/XSSF千万行会直接撑爆堆内存关键代码思路伪代码// 1. 初始化Excel写入器流式只保留少量行在内存 ExcelWriter writer EasyExcel.write(filePath, OrderDTO.class).build(); Long lastId 0L; int pageSize 1000; while (true) { // 2. 游标分页查询一批数据仅1000条 ListOrder pageList orderMapper.selectByCursor(lastId, pageSize); if (CollectionUtils.isEmpty(pageList)) { break; // 数据读取完毕 } // 3. 分批写入文件写完立即释放集合内存 writer.write(pageList); // 4. 更新游标ID lastId pageList.get(pageList.size() - 1).getOrderId(); // 手动GC可选加速内存回收 pageList.clear(); } // 收尾 writer.finish();3. 异步任务解决前端超时、服务阻塞千万级导出耗时分钟级绝对不能同步接口返回技术选型Spring Task / XXL-Job / RabbitMQ/RocketMQ 异步队列流程前端点击导出 → 调用同步接口仅创建导出任务记录返回「任务正在处理」消息 / 定时任务消费执行上述「DB 分页 流式写文件」逻辑任务完成文件上传至OSS/MinIO/ 本地文件服务器数据库更新任务状态前端轮询任务状态完成后展示下载链接限流保护限制同时运行的导出任务数如最多 3 个防止批量导出打垮服务 / DB4. 文件存储与分片超大文件优化千万行 Excel 单文件会出现打开卡顿、传输慢、损坏风险两种优化方式 1文件拆分推荐给运营使用每10 万20 万行拆分一个 Excel 文件最终生成订单数据_01.xlsx、订单数据_02.xlsx打包为 ZIP 压缩包供下载。优势单个文件体积小打开、下载都流畅方式 2导出为 CSV大数据量终极方案Excel 单文件行数有隐性上限千万级优先导出 CSVCSV 纯文本格式写入速度远快于 ExcelIO 开销极低Excel/WPS/ 记事本均可直接打开兼容性强流式逐行拼接文本写入内存占用最低三、备选方案按场景选用方案 1数据库原生导出运维 / 技术侧快速导出不面向前端适合运维后台、离线统计零应用压力MySQL into outfile服务器本地导出-- 导出订单表到服务器本地CSV走DB层流式无应用内存压力 SELECT order_id, user_id, amount, create_time FROM order WHERE create_time BETWEEN xxx AND xxx INTO OUTFILE /data/export/order_2026.csv CHARACTER SET utf8mb4 FIELDS TERMINATED BY , ENCLOSED BY LINES TERMINATED BY \n;优点速度最快、不占用应用服务资源限制需要 MySQL 服务器文件写入权限不能直接给前端使用适合离线备份方案 2大数据架构数据量持续暴涨亿级数据如果后续订单突破亿级引入数仓组件订单数据实时同步到 ClickHouse/Hivebinlog 同步导出查询全部走数仓彻底隔离线上主库配合 DataX/Sqoop 做离线批量导出四、关键避坑点生产必看** 禁止全表 Select *** 只查询业务需要的字段减少网络传输、内存、文件体积。严禁深分页 Limit N,M数据量越大偏移分页越慢坚持使用ID 游标分页。线上导出必须走从库大查询会拉高 CPU、IO主库优先保障下单、支付核心业务。JVM 参数微调配合流式导出 适当调大堆内存但不要依赖堆内存存数据-Xms2g -Xmx2g开启堆内存溢出快照-XX:HeapDumpOnOutOfMemoryError。超时配置 调整数据库连接超时、文件写入超时、网关超时避免中途中断。权限与清理 导出文件设置自动过期删除如 7 天防止磁盘占满。五、方案选型总结数据量级推荐方案百万级以内异步任务 EasyExcel 游标分页流式导出单 Excel/CSV千万级异步 游标分页 拆分多文件 ZIP / 直接导出 CSV亿级 数据同步到 ClickHouse/Hive 离线导出运维临时导出MySQLinto outfile原生导出最简落地步骤直接照着做订单表order_id、create_time确认索引存在接入 EasyExcel实现ID 游标分页 逐批流式写入接入 MQ / 定时任务做异步导出前端轮询状态导出走MySQL 从库千万行优先输出 CSV 或拆分 Excel配置文件自动清理、任务限流。