SEO教程

SEO教程

Products

当前位置:首页 > SEO教程 >

MyBatis批量插入,如何从5分钟缩短至3秒?

96SEO 2026-05-06 19:51 16


宝子们,上周我接到了一个超“刺激”的数据迁移任务,要把老系统中的10万条数据导入到新系统。想着用MyBatis批量插入应该是小case,结果现实却给了我狠狠一击!Zui初的代码跑起来插入10万条数据居然整整耗时5分钟!这要是放到生产环境,用户不得分分钟把我“吐槽”上热搜?领导也坐不住了直接下达指令:必须优化,越快越好!于是我开启了一场和时间赛跑的性Neng优化之旅,没想到Zui后真让我把时间从5分钟缩短到了3秒,今天就来给大家分享一下我douZuo了些什么。

MyBatis批量插入,如何从5分钟缩短至3秒?

惨痛的开局:当“简单粗暴”遇上大数据量

事情是这样的,Zui开始我写代码的时候,图省事,直接来了个Zui常规的foreach循环单条插入。代码逻辑简单得令人发指,就是遍历List,然后一条条调用insert方法。我想着,反正数据库连接池在那摆着,Neng慢到哪去?

结果一运行,进度条走得比蜗牛还慢。我盯着屏幕kan了足足五分钟,程序才跑完。那一刻,我的内心是崩溃的。这哪里是数据迁移,简直是数据“散步”。

经过一番排查,我发现这种写法简直是性Neng杀手。每一次循环插入,dou要经历一次完整的数据库交互流程:建立连接、SQL语法解析、执行计划生成、数据写入磁盘以及事务提交。当数据量达到10万级别时这些微小的开销累积起来就成了天文数字。数据库CPU直接飙升到100%,磁盘I/O也打满了整个系统差点瘫痪。

第一次优化:从“单兵作战”到“集团军冲锋”

痛定思痛,我决定放弃这种单条插入的“自杀式”写法。既然一条条送太慢,那就打包一起送!我把目光投向了MyBatis的``标签,打算拼接一条超长的SQL语句。

思路hen简单,就是利用XML中的``标签,把List中的数据拼成一个`INSERT INTO ... VALUES , , ...`的形式。Mapper XML大概长这样:


    INSERT INTO user  VALUES
    
    

Java代码层面为了避免一次性生成的SQL过长导致数据库报错,我采用了分批插入的策略,每批处理1000条数据:

int batchSize = 1000;
for ; i += batchSize) {
    int end = Math.min);
    List batch = userList.subList;
    userMapper.batchInsert;
}

当我满怀期待地 运行代码时结果让我眼前一亮!插入10万条数据的时间从原来的5分钟,直接降到了30秒,效率提升了整整10倍!这主要是因为批量SQL减少了网络往返次数,原来每插入一条数据dou要进行一次网络通信,现在一次Ke以发送多条数据,大大节省了时间。同时数据库也只需要对一条SQL语句进行解析和执行,减少了重复劳动。这就好比原来你要一个一个地搬砖,现在Ke以一次搬一摞,速度自然就快了起来。

不过30秒的时间还是不够理想,离领导要求的“越快越好”还有一定差距,而且这种Zuo法有个巨大的隐患:Ru果数据量再大一点,生成的SQL长度可Neng会超过MySQL的`max_allowed_packet`限制,直接抛出异常。于是我决定继续深入挖掘优化空间。

第二次优化:JDBC批处理与“重写”的秘密

虽然``解决了部分问题,但我总觉得MyBatis肯定还有geng高级的玩法。经过查阅资料,我发现了JDBC批处理这个“秘密武器”。

这里的关键点有两个:一个是MyBatis的`ExecutorType.BATCH`模式,另一个是MySQL驱动连接参数`rewriteBatchedStatements=true`。

我们需要在Spring Boot的配置文件中开启那个神奇的参数。这个参数的作用是让MySQL驱动在底层偷偷把多条INSERT语句重写成一条,从而减少数据库的解析和执行次数。

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/your_database?rewriteBatchedStatements=true
    username: your_username
    password: your_password
    driver-class-name: com.mysql.cj.jdbc.Driver

接着,在Java代码中,我们不Neng再用常规的SqlSession了必须手动指定`ExecutorType.BATCH`。代码稍微有点变化,需要自己控制Session的开启和提交:

@Autowired
private SqlSessionFactory sqlSessionFactory;
public void batchInsertWithExecutor {
    try ) {
        UserMapper mapper = sqlSession.getMapper;
        for ; i++) {
            mapper.insert);
            // 每隔1000条刷新一次防止缓存过大
            if  % 1000 == 0) {
                sqlSession.flushStatements;
                sqlSession.clearCache;
            }
        }
        sqlSession.flushStatements;
        sqlSession.commit;
    }
}

当我 运行代码时插入10万条数据的时间从30秒直接降到了8秒!这简直太神奇了。在`ExecutorType.BATCH`模式下MyBatis会先将SQL语句缓存起来直到调用`flushStatements`或`commit`时才一次性发送给数据库。配合`rewriteBatchedStatements=true`,MySQL驱动会在底层把这些语句合并成一条高效的SQL。就好像原来你是一次送一块砖到工地,现在你Ke以一次送一车砖,而且还把这些砖整齐地码放好了效率自然就geng高了。

第三次优化:多线程并行,榨干服务器性Neng

经过前两次优化,虽然插入时间Yi经大幅缩短,但我还是觉得不够快。kan着服务器监控面板上那还有余量的CPU核心,我决定引入多线程并行插入的方式,充分利用服务器的多核CPU资源。

具体实现思路是将数据分成多个小批次每个批次交给一个独立的线程去处理。这里有个坑需要注意:每个线程必须拥有自己独立的`SqlSession`,否则多线程并发操作同一个Session会导致各种莫名其妙的并发问题。

我创建了一个固定大小的线程池,然后将10万条数据切分,提交给线程池并行执行:

public void parallelBatchInsert {
    int threadCount = 8; // 根据数据库连接池大小和CPU核心数调整
    int batchSize = userList.size / threadCount;
    ExecutorService executor = Executors.newFixedThreadPool;
    List futures = new ArrayList<>;
    for  {
        int start = i * batchSize;
        int end =  ? userList.size :  * batchSize;
        List subList = userList.subList;
        futures.add -> {
            // 每个线程内部调用之前的批处理方法
            batchInsertWithExecutor; 
        }));
    }
    // 等待所有任务完成
    for  {
        try {
            future.get;
        } catch  {
            throw new RuntimeException;
        }
    }
    executor.shutdown;
}

当我怀着忐忑的心情 运行代码时奇迹发生了!插入10万条数据的时间从8秒直接降到了3秒,这简直太不可思议了!从Zui初的5分钟到现在的3秒,性Neng提升了整整100倍,我自己dou被这个结果惊到了。多线程并行插入,每个线程负责一部分数据的插入,大大提高了吞吐量。

避坑指南:那些年我踩过的“雷”

在这场优化之旅中,我也遇到了不少坑,好在dou一一解决了现在就把这些经验分享给大家,希望Neng帮助大家少走弯路。

1. 内存溢出的恐惧

在Zui初的实现中,我是一次性将10万条数据加载到内存中进行处理的,这就带来了一个潜在的风险——内存溢出。当数据量非常大时一次性加载所有数据会占用大量的内存,导致JVM内存不足,抛出`OutOfMemoryError`异常。

为了解决这个问题,我采用了分页读取 + 分批插入的策略。通过`countTotal`方法获取数据的总条数,然后根据设定的`pageSize`进行分页读取。每次只处理一页数据,大大减少了内存的占用,避免了内存溢出的问题。

int pageSize = 1000;
int total = countTotal;
for  {
    List page = selectByPage;
    batchInsertWithExecutor;
}
2. 主键冲突的尴尬

在多线程并行插入时要特别注意主键冲突的问题。Ru果数据中包含唯一主键,多个线程同时插入可Neng会导致主键冲突异常。Ke以通过在数据库表上添加唯一约束,或者在插入前进行主键校验等方式来避免。Ru果业务允许,使用自增主键或者分布式ID生成器也是不错的选择。

3. `rewriteBatchedStatements`不生效?

有时候你会发现,明明加了参数,速度却没提升。这通常有几个原因: 一是URL参数拼写错误,我就曾经因为粗心把`rewriteBatchedStatements`写成了`rewriteBatchStatements`,导致参数不生效。 二是MySQL驱动版本太旧,老版本的驱动可Neng不支持这个参数,记得升级到`Connector/J 5.1.13`以上版本。 三是未使用ExecutorType.BATCH,这个模式必须开启,否则驱动没法重写SQL。

4. 事务一致性的考量

多线程并行插入虽然快,但也有代价。Ru果需要保证强事务一致性,这种方式可Neng不太适用。因为每个线程dou有自己的事务,Ru果某个线程插入失败,其他线程Yi经插入的数据无法回滚。Ru果必须保证事务一致性,Ke以考虑使用分布式事务解决方案,如Seata等,或者退回到单线程的批处理模式。毕竟在数据一致性面前,速度有时候得让路。

通过这三次优化,我深刻体会到了性Neng优化的魅力和挑战。从Zui初的5分钟到Zui终的3秒,不仅仅是数字的变化,geng是对底层原理的深入理解。

优化方案 耗时 提升倍数
循环单条插入 300秒 基准
批量SQL 30秒 10倍
JDBC批处理 8秒 37倍
多线程并行 3秒 100倍

在实际开发中,我们不Neng满足于代码Neng跑就行,要不断追求geng高的性Neng和geng好的用户体验。希望我的优化经验Neng对大家有所帮助,Ru果你也有类似的性Neng优化经历,欢迎在评论区分享哦!别忘了技术这条路,就是不断填坑和爬坑的过程,加油!


标签: 之路

SEO优化服务概述

作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。

百度官方合作伙伴 白帽SEO技术 数据驱动优化 效果长期稳定

SEO优化核心服务

网站技术SEO

  • 网站结构优化 - 提升网站爬虫可访问性
  • 页面速度优化 - 缩短加载时间,提高用户体验
  • 移动端适配 - 确保移动设备友好性
  • HTTPS安全协议 - 提升网站安全性与信任度
  • 结构化数据标记 - 增强搜索结果显示效果

内容优化服务

  • 关键词研究与布局 - 精准定位目标关键词
  • 高质量内容创作 - 原创、专业、有价值的内容
  • Meta标签优化 - 提升点击率和相关性
  • 内容更新策略 - 保持网站内容新鲜度
  • 多媒体内容优化 - 图片、视频SEO优化

外链建设策略

  • 高质量外链获取 - 权威网站链接建设
  • 品牌提及监控 - 追踪品牌在线曝光
  • 行业目录提交 - 提升网站基础权威
  • 社交媒体整合 - 增强内容传播力
  • 链接质量分析 - 避免低质量链接风险

SEO服务方案对比

服务项目 基础套餐 标准套餐 高级定制
关键词优化数量 10-20个核心词 30-50个核心词+长尾词 80-150个全方位覆盖
内容优化 基础页面优化 全站内容优化+每月5篇原创 个性化内容策略+每月15篇原创
技术SEO 基本技术检查 全面技术优化+移动适配 深度技术重构+性能优化
外链建设 每月5-10条 每月20-30条高质量外链 每月50+条多渠道外链
数据报告 月度基础报告 双周详细报告+分析 每周深度报告+策略调整
效果保障 3-6个月见效 2-4个月见效 1-3个月快速见效

SEO优化实施流程

我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:

1

网站诊断分析

全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。

2

关键词策略制定

基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。

3

技术优化实施

解决网站技术问题,优化网站结构,提升页面速度和移动端体验。

4

内容优化建设

创作高质量原创内容,优化现有页面,建立内容更新机制。

5

外链建设推广

获取高质量外部链接,建立品牌在线影响力,提升网站权威度。

6

数据监控调整

持续监控排名、流量和转化数据,根据效果调整优化策略。

SEO优化常见问题

SEO优化一般需要多长时间才能看到效果?
SEO是一个渐进的过程,通常需要3-6个月才能看到明显效果。具体时间取决于网站现状、竞争程度和优化强度。我们的标准套餐一般在2-4个月内开始显现效果,高级定制方案可能在1-3个月内就能看到初步成果。
你们使用白帽SEO技术还是黑帽技术?
我们始终坚持使用白帽SEO技术,遵循搜索引擎的官方指南。我们的优化策略注重长期效果和可持续性,绝不使用任何可能导致网站被惩罚的违规手段。作为百度官方合作伙伴,我们承诺提供安全、合规的SEO服务。
SEO优化后效果能持续多久?
通过我们的白帽SEO策略获得的排名和流量具有长期稳定性。一旦网站达到理想排名,只需适当的维护和更新,效果可以持续数年。我们提供优化后维护服务,确保您的网站长期保持竞争优势。
你们提供SEO优化效果保障吗?
我们提供基于数据的SEO效果承诺。根据服务套餐不同,我们承诺在约定时间内将核心关键词优化到指定排名位置,或实现约定的自然流量增长目标。所有承诺都会在服务合同中明确约定,并提供详细的KPI衡量标准。

SEO优化效果数据

基于我们服务的客户数据统计,平均优化效果如下:

+85%
自然搜索流量提升
+120%
关键词排名数量
+60%
网站转化率提升
3-6月
平均见效周期

行业案例 - 制造业

  • 优化前:日均自然流量120,核心词无排名
  • 优化6个月后:日均自然流量950,15个核心词首页排名
  • 效果提升:流量增长692%,询盘量增加320%

行业案例 - 电商

  • 优化前:月均自然订单50单,转化率1.2%
  • 优化4个月后:月均自然订单210单,转化率2.8%
  • 效果提升:订单增长320%,转化率提升133%

行业案例 - 教育

  • 优化前:月均咨询量35个,主要依赖付费广告
  • 优化5个月后:月均咨询量180个,自然流量占比65%
  • 效果提升:咨询量增长414%,营销成本降低57%

为什么选择我们的SEO服务

专业团队

  • 10年以上SEO经验专家带队
  • 百度、Google认证工程师
  • 内容创作、技术开发、数据分析多领域团队
  • 持续培训保持技术领先

数据驱动

  • 自主研发SEO分析工具
  • 实时排名监控系统
  • 竞争对手深度分析
  • 效果可视化报告

透明合作

  • 清晰的服务内容和价格
  • 定期进展汇报和沟通
  • 效果数据实时可查
  • 灵活的合同条款

我们的SEO服务理念

我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。

提交需求或反馈

Demand feedback