【Mybatis】使用批处理优化百万数据量插入

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xingceng.bimsys.dao.BimModelDataDao">
    <insert id="saveBatch" parameterType="java.util.List">
        INSERT INTO `bimangle_data`(`entity_id`,`attribute_id`,`value_id`,`name`,`value`,`model_id`) VALUES
        <foreach collection="item" separator="," item="item">
            (#{item.entityId},#{item.attributeId},#{item.valueId},#{item.name},#{item.value},#{item.modelId})
        </foreach>
    </insert>

使用MyBatis 原生批量插入时,当传入的LIst数据量过大就会出现以下错误
在这里插入图片描述
这是因为使用 MyBatis 原生批量插入拼接的插入 SQL 大小是 4.56M,而默认情况下 MySQL 可以执行的最大 SQL 为 4M,那么在程序执行时就会报错了。

解决方案:

将LIst分成多份循环插入,也就是分片批量插入

第一步:我们先要添加 Guava 框架的支持,在 pom.xml 中添加以下引用:

  <!-- google guava 工具类 -->
        <!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>31.0.1-jre</version>
        </dependency>

第二部:改造我们的 MyBatis 批量插入代码

  long stime = System.currentTimeMillis(); // 统计开始时间
                    System.out.println("一共插入"+bimangleDataList.size()+"条数据");
                    // 分片批量插入
                    // 分为 n 份,每份 1000 条
                    List<List<BimangleData>> listPartition = Lists.partition(bimangleDataList, 1000);
                    // 分片批量插入
                    for (List<BimangleData> item : listPartition) {
                        bimModelDataDao.saveBatch(item);
                    }
                    long etime = System.currentTimeMillis(); // 统计结束时间
                    System.out.println("执行时间:" + (etime - stime));

读取三个不同大小的模型算量测试

27152 1.7秒

72561 4秒

322830 18秒

最终结果

一次插入32w算量数据从90分钟优化成18秒

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值