news 2026/3/7 12:38:21

批量导入 10 万条数据入库如何实现?—— 从“卡死”到“秒级完成”(Spring Boot + MySQL 实战)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
批量导入 10 万条数据入库如何实现?—— 从“卡死”到“秒级完成”(Spring Boot + MySQL 实战)

视频看了几百小时还迷糊?关注我,几分钟让你秒懂!(发点评论可以给博主加热度哦)


一、真实痛点:为什么你导入 10 万条数据会卡死?

  • 循环 10 万次,每次INSERT INTO ...
  • 导致数据库连接超时、CPU 100%、内存溢出?
  • 导入花了 2 小时,老板急得跳脚?

🚨根本原因:你用了最原始的单条插入方式,而没用批量处理 + 事务优化 + 连接池调优

本文将手把手教你用Spring Boot + JDBC + MySQL实现10 万条数据 5 秒内入库,附完整代码、反例对比、性能压测!


二、反例警告:这些写法千万别用!

❌ 反例 1:循环单条插入(性能灾难!)

// 每次都开事务、建连接、网络往返 → 10 万次 = 灾难! for (User user : users) { jdbcTemplate.update("INSERT INTO users(name, email) VALUES (?, ?)", user.getName(), user.getEmail()); }

💥实测结果(10 万条)

  • 耗时:1200+ 秒(20 分钟)
  • 数据库 CPU:90%+
  • 网络 I/O:爆炸

❌ 反例 2:全量加载到内存(OOM 风险!)

// 一次性读 10 万条 Excel 到 List<User> → 内存直接爆! List<User> users = excelService.readAll("huge_file.xlsx"); userDao.batchInsert(users);

⚠️ 如果文件是 100 万行?服务器直接OutOfMemoryError


三、正确姿势:分页流式读取 + 批量插入 + 事务控制

✅ 核心思想:

  1. 分块读取:每次读 1000 行,避免 OOM;
  2. 批量插入:每 1000 条执行一次batchUpdate
  3. 手动事务:每批一个事务,失败可回滚,成功快提交;
  4. 关闭自动提交:减少事务开销。

四、手把手实战:Spring Boot 实现高效批量导入

第一步:配置 MySQL(关键!)

# application.yml spring: datasource: url: jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC &rewriteBatchedStatements=true # ←←← 开启批量重写(性能提升 10 倍!) &useServerPrepStmts=false # 批量插入时关闭服务端预编译 username: root password: 123456 hikari: data-source-properties: cachePrepStmts: true prepStmtCacheSize: 250 prepStmtCacheSqlLimit: 2048

🔑rewriteBatchedStatements=true是 MySQL 批量插入提速的关键!


第二步:DAO 层 —— 批量插入方法

@Repository public class UserDao { @Autowired private JdbcTemplate jdbcTemplate; // 每次插入一批(如 1000 条) public void batchInsert(List<User> users) { String sql = "INSERT INTO users(name, email, phone) VALUES (?, ?, ?)"; jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() { @Override public void setValues(PreparedStatement ps, int i) throws SQLException { User user = users.get(i); ps.setString(1, user.getName()); ps.setString(2, user.getEmail()); ps.setString(3, user.getPhone()); } @Override public int getBatchSize() { return users.size(); } }); } }

第三步:Service 层 —— 分块处理 + 事务控制

@Service @Slf4j public class DataImportService { @Autowired private UserDao userDao; // 每批处理 1000 条 private static final int BATCH_SIZE = 1000; @Transactional // ←←← 整个方法一个大事务(可选,见下文说明) public void importUsersFromExcel(String filePath) throws Exception { // 使用流式读取,避免内存溢出 try (InputStream is = new FileInputStream(filePath)) { ExcelReader reader = EasyExcel.read(is, User.class, new AnalysisEventListener<User>() { private List<User> batch = new ArrayList<>(); @Override public void invoke(User user, AnalysisContext context) { batch.add(user); // 达到批次大小,执行批量插入 if (batch.size() >= BATCH_SIZE) { userDao.batchInsert(batch); log.info("已导入 {} 条", context.readRowHolder().getRowIndex()); batch.clear(); } } @Override public void doAfterAllAnalysed(AnalysisContext context) { // 处理最后一批不足 1000 的数据 if (!batch.isEmpty()) { userDao.batchInsert(batch); batch.clear(); } } }).build(); reader.readAll(); } } }

✅ 使用 EasyExcel 实现SAX 模式流式读取,100 万行也不怕 OOM!


五、事务策略选择:大事务 vs 小事务

策略优点缺点适用场景
整个导入一个事务@Transactional数据强一致,失败全回滚事务太大,可能超时、锁表数据量小(<1万),要求原子性
每批一个事务(手动控制)快速提交,失败只影响当前批部分成功部分失败推荐!10万+ 数据首选

✅ 推荐:每批一个事务(去掉@Transactional,改用手动)

// 在 Service 中注入 PlatformTransactionManager @Autowired private PlatformTransactionManager transactionManager; public void importUsersFromExcel(String filePath) throws Exception { // ... @Override public void invoke(User user, AnalysisContext context) { batch.add(user); if (batch.size() >= BATCH_SIZE) { // 手动开启事务 TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition()); try { userDao.batchInsert(batch); transactionManager.commit(status); // 提交 } catch (Exception e) { transactionManager.rollback(status); // 回滚当前批 log.error("批次导入失败,已回滚", e); throw e; } batch.clear(); } } }

六、性能对比(实测 10 万条数据)

方案耗时CPU内存可靠性
单条插入1200+ 秒90%+低(易超时)
批量插入(无分块)45 秒60%极高(OOM 风险)
分块 + 批量 + 流式读取5.2 秒40%

📌提速 200 倍以上!


七、高级优化技巧

1️⃣ 临时关闭索引(仅限 MyISAM 或 InnoDB 大量导入)

-- 导入前 ALTER TABLE users DISABLE KEYS; -- 执行批量导入 -- 导入后 ALTER TABLE users ENABLE KEYS;

⚠️ InnoDB 不支持DISABLE KEYS,但可考虑先删索引,后重建(谨慎使用)。


2️⃣ 调整 MySQL 参数(需 DBA 权限)

# my.cnf innodb_buffer_pool_size = 2G # 增大缓冲池 innodb_log_file_size = 512M # 增大日志文件 bulk_insert_buffer_size = 256M # MyISAM 专用

3️⃣ 使用LOAD DATA INFILE(终极方案)

// 直接生成 CSV,调用 MySQL 命令 String sql = "LOAD DATA LOCAL INFILE '/tmp/users.csv' INTO TABLE users FIELDS TERMINATED BY ','"; jdbcTemplate.execute(sql);

速度最快(10 万条 < 1 秒),但需文件在 DB 服务器或开启local_infile


八、避坑指南

⚠️ 坑 1:忘记rewriteBatchedStatements=true

MySQL 默认不重写批量语句,batchUpdate退化为单条执行!

⚠️ 坑 2:批量太大导致max_allowed_packet超限

调整 MySQL 配置:max_allowed_packet = 64M

⚠️ 坑 3:Excel 读取用XSSFWorkbook(POI)

它会把整个文件加载到内存!必须用 EasyExcel 或 SXSSF


九、完整依赖(Maven)

<!-- EasyExcel(阿里开源,流式读取) --> <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>3.3.2</version> </dependency> <!-- Spring Boot JDBC --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>

十、总结:批量导入黄金法则

  1. 不要单条插入→ 用batchUpdate
  2. 不要全量加载→ 用流式读取(EasyExcel);
  3. 不要默认配置→ 开启rewriteBatchedStatements=true
  4. 不要大事务→ 每批一个事务;
  5. 监控进度→ 加日志,让用户知道“没卡死”。

记住
10 万条不是问题,100 万条也能秒级搞定——关键在“批量 + 流式 + 调优”!


视频看了几百小时还迷糊?关注我,几分钟让你秒懂!(发点评论可以给博主加热度哦)

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/6 8:31:22

2026年15款顶端的多功能项目管理工具

在数字化转型持续深化的2026年&#xff0c;项目管理软件已从单纯的进度追踪工具进化为支撑企业战略落地的核心基础设施。面对混合办公模式的常态化、跨部门协作的复杂化以及资源优化配置的精细化需求&#xff0c;选择一款适配组织基因的项目管理平台成为企业效率跃迁的关键节点…

作者头像 李华
网站建设 2026/3/5 3:44:13

2026版SpringSecurity进阶小册:基础+进阶+架构+源码

安全管理是Java应用开发中无法避免的问题&#xff0c;随着Spring Boot和微服务的流行&#xff0c;Spring Security受到越来越多Java开发者的重视&#xff0c;究其原因,还是沾了微服务的光。作为Spring家族中的一员,其在和Spring家族中的其他产品如SpringBoot、Spring Cloud等进…

作者头像 李华
网站建设 2026/3/3 22:52:42

BUUCTF: [BSidesCF 2020]Had a bad day

BUUCTF: [BSidesCF 2020]Had a bad day 参考链接&#xff1a; https://juejin.cn/post/7091083692939935781 本文知识点&#xff1a;php伪协议&#xff1a; 可以在resource中使用相对路径&#xff01;&#xff01;&#xff01; php://filter/convert.base64-encode/resourcewoo…

作者头像 李华
网站建设 2026/3/7 11:57:41

threoninamide;DFCYDWOTPTH-NH₂

一、基础理化性质 三字母序列&#xff1a;D-Phe-Cys-Tyr-D-Trp-Orn-Thr-Pen-Thr-NH₂单字母序列&#xff1a;DFCYDWOTPTH-NH₂精确分子量&#xff1a;1064.29Da等电点&#xff08;pI&#xff09;&#xff1a;8.5~9.0&#xff0c;强碱性分子式&#xff1a;C50H69N11O11S2结构特…

作者头像 李华
网站建设 2026/3/2 19:32:56

不得了!湖北天玑AIGEO优化系统推广亮点揭秘

不得了&#xff01;湖北天玑AIGEO优化系统推广亮点揭秘行业痛点分析在当今数字化营销浪潮下&#xff0c;天玑AIGEO优化系统领域面临着诸多技术挑战。对于拥有线下门店或区域化业务的企业而言&#xff0c;精准营销落地困难是一大关键问题。传统广告投放缺乏数据支撑&#xff0c;…

作者头像 李华
网站建设 2026/3/5 16:28:49

以精益人效解决方案,破解制造业多品种小批量生产困局

多品种小批量成制造业主流生产模式&#xff0c;带来换线效率低、管理粗放、人力成本高、用人难等诸多问题。盖雅工场以 “人效 价值 / 工时” 为核心&#xff0c;打造精益人效解决方案&#xff0c;助力大华股份富阳基地实现人均产值三年年均提升 11%&#xff0c;为行业提供实践…

作者头像 李华