Mybatis批量插入,形式不同性能也不同

01 引言

批量插入数据是我们业务中经常遇到的,我们习惯了手搓sql如:

insert into user_info (`name`, `age`, `created_time`) values 
<foreach item ="item" collection="list"  separator=",">
     (#{item.name}, #{item.age}, #{item.createdTime})
</foreach>

这样的脚本,适用于数据量不大的情况,基本满足业务需求,但是却存在安全隐患。当传输的数据量过大时,可能会引起异常。

本节,我们将对比不同的写法以及响应的时间的消耗。

02 日常批量插入

insert into tb (col1, col2) values (val1, val2),......

上面的这种写法确实比一条条的数据入库的速度快太多,我们这里只横向对比不同的批量插入。我们先看看Mysql官方给的Insert执行的流程。

官网地址:https://dev.mysql.com/doc/refman/8.4/en/insert-optimization.html

2.1 安全隐患

所谓的安全隐患,其实就是Mysql的一些配置。而这些配置直接影响sql是否会执行以及执行的效率。

  • bulk_insert_buffer_size
  • max_allowed_packet

bulk_insert_buffer_size

Myisam引擎参数,在使用myisam引擎执行INSERT ... SELECT,INSERT ... VALUES (...), (...), ...,LOAD DATA INFILE批量插入时,会采用一种缓存树的内存结构来优化插入速度。默认8M。

max_allowed_packet

控制了 MySQL 服务器接收和发送的最大数据包的大小,默认64M。

因为小编测试的Mysql引擎使用的是innodb,所以暂时不考虑第一个参数。小编准备了10W条数据一次全部插入到数据库,就报错了:

所以呢,当一次插入的数据达到一定的数据就会出现异常。

2.2 分批插入

我们通过1W条数据测试一下,不同数据插入的结果:

@Test
public void test01() {
   
   
    List<UserInfo> list = new ArrayList<>();
    for (int i = 1; i <= 10000; i++) {
   
   
        UserInfo userInfo = new UserInfo();
        userInfo.setName("test" + i);
        userInfo.setAge(new Random().nextInt(1,90));
        userInfo.setCreatedTime(LocalDateTime.now());
        list.add(userInfo);
    }

    List<List<UserInfo>> partition = Lists.partition(list, 5000);
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    for (List<UserInfo> userInfos : partition) {
   
   
        userInfoMapper.insertBatch(userInfos);
    
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

智_永无止境

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值