mybatis-plus批量插入测试

172 阅读2分钟

测试插入100万条生成的学生数据:

使用技术说明:

SpringBlade框架

前端:saber vue3版

后端:后端SpringBoot版

数据库:mysql8.0.37,dev.mysql.com/downloads/i…

JDK17: Azul Zulu,www.azul.com/downloads/?…

测试表情况:stu_student 有主键id,未增加其他索引 image.png

1、使用MyBatis-Plus提供的save方法

for (int i = 0; i < 1000000; i++) {
    StuStudent temp = new StuStudent();
    temp.setName("stu_"+i);
    temp.setGender((i%2==1?1:2)+"");
    temp.setStudentNumber("5300"+i);
    temp.setBirthday(LocalDate.now());
    temp.setEntranceTime(LocalDate.now());
    stuStudentService.save(temp);
}

image.png 空表插入100万数据耗时:3小时32分51秒 12770288ms

期间100万条数据单条数据独立事务。

2、使用MyBatis-Plus提供的saveBatch方法

ArrayList<StuStudent> studentList = new ArrayList<>();
for (int i = 1000000; i < 2000000; i++) {
    StuStudent temp = new StuStudent();
    temp.setName("stu_"+i);
    temp.setGender((i%2==1?1:2)+"");
    temp.setStudentNumber("5300"+i);
    temp.setBirthday(LocalDate.now());
    temp.setEntranceTime(LocalDate.now());
    studentList.add(temp);
}
long startMillis = System.currentTimeMillis();
stuStudentService.saveBatch(studentList);
long endMillis = System.currentTimeMillis();
System.out.println("耗时:" + (endMillis - startMillis) + "ms");

image.png image.png 已有100万数据,插入100万数据耗时:28分11秒 1691193ms

期间100万条数据完整事务。

1000条数据为单个批次。 image.png

3、使用MyBatis-Plus提供的InsertBatchSomeColumn方法

HttpServletRequest request = WebUtil.getRequest();
BladeUser bladeUser = SecureUtil.getUser(request);

ArrayList<StuStudent> studentList = new ArrayList<>();
for (int i = 0; i < 1000000; i++) {
    StuStudent temp = new StuStudent();
    temp.setName("stu_"+i);
    temp.setGender((i%2==1?1:2)+"");
    temp.setStudentNumber("5300"+i);
    temp.setBirthday(LocalDate.now());
    temp.setEntranceTime(LocalDate.now());
    temp.setCreateTime(new Date());
    temp.setUpdateTime(new Date());
    temp.setCreateUser(bladeUser.getUserId());
    temp.setUpdateUser(bladeUser.getUserId());
    temp.setCreateDept(Long.parseLong(bladeUser.getDeptId()));
    temp.setStatus(1);
    temp.setIsDeleted(0);
    studentList.add(temp);
}

long startMillis = System.currentTimeMillis();
int batchCount = (int)Math.ceil(studentList.size()/2000.0);
for (int i = 0; i < batchCount; i++) {
    List<StuStudent> studentListTemp;
    int subStartIndex = i*2000;
    int subEndIndex;
    if (i < batchCount-1){
       subEndIndex = subStartIndex+2000;
    }else if (i == batchCount-1){
       subEndIndex = studentList.size();
    }else{
       continue;
    }
    log.info("subStartIndex:{};subEndIndex:{}", subStartIndex, subEndIndex);
    studentListTemp = studentList.subList(subStartIndex,subEndIndex);
    log.info("studentListTemp.size():{}", studentListTemp.size());
    stuStudentDao.insertBatchSomeColumn(studentListTemp);
}
long endMillis = System.currentTimeMillis();
log.info("耗时:{}ms", endMillis - startMillis);

image.png 已有500万数据,插入100万数据耗时:14分57秒 897118ms

期间100万条数据每2000条为一个完整事务。

改为每次5000条测试

image.png 已有300万数据,插入100万数据耗时:14分54秒 894317ms

改为每次10000条测试

image.png

image.png 已有400万数据,插入100万数据耗时:14分54秒 894105ms

当前环境max_allowed_packet的大小为64M

image.png

参考文档:mybatis-plus批量插入之 insertBatchSomeColumn方法blog.csdn.net/m0_51406695…

参考文档:mybatis批量插入一次能插入1万条数据吗 zhuanlan.zhihu.com/p/444215181