news 2026/2/7 16:51:22

批量导入 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/2/7 8:26:43

不止简历筛选:多家招聘系统厂商能力 PK

在企业数字化转型浪潮中&#xff0c;招聘作为人才引入的关键环节&#xff0c;其效率与质量直接影响企业发展。招聘系统&#xff08;ATS&#xff09;作为 HR SaaS 领域的核心工具&#xff0c;能实现简历解析、人岗匹配、流程自动化等功能&#xff0c;帮助企业降低人工成本、提升…

作者头像 李华
网站建设 2026/2/5 20:40:09

选对 HR SaaS 事半功倍!多家厂商横向分析

在企业数字化转型加速的当下&#xff0c;HR SaaS 系统已从 “工具辅助” 升级为 “战略赋能” 的核心载体&#xff0c;选对系统直接影响人力管理效率与人才战略落地。但当前市场厂商林立&#xff0c;产品功能、适配场景差异显著&#xff0c;企业常陷入 “选贵的还是选对的”“功…

作者头像 李华
网站建设 2026/2/7 9:36:02

Vue3 + 高德地图:实现多功能标记点管理与事件交互

概述 在现代前端GIS应用开发中&#xff0c;地图标记点&#xff08;Marker&#xff09;的管理是核心功能之一。本文将详细介绍如何基于Vue3、Ant Design Vue 4.0和高德地图API&#xff0c;实现一个高度可配置、支持多类型标记点、具备丰富交互功能的标记点管理系统。 技术栈 V…

作者头像 李华
网站建设 2026/2/7 3:33:00

【计算机毕业设计案例】基于SpringBoot的蔬菜种植管理蔬菜种植园管理系统 绿色菜园智能管理平台系统设计与实现(程序+文档+讲解+定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华