Mysql默认配置导致Mybatis-plus批处理性能受限
结论:
1、默认情况下,Mysql驱动在在默认情况下会无视executeBatch()语句;把我们期望批量执行的一组sql语句拆散,一条一条地发给MySQL数据库,批量插入实际上是单条插入,直接造成较低的性能。
2、MySQL的JDBC连接的url中要加&rewriteBatchedStatements=true参数,并保证5.1.13以上版本的驱动,才能实现高性能的批量插入,另外这个选项对INSERT/UPDATE/DELETE都有效。
url: jdbc:mysql://ip地址:3306/emr?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC #&rewriteBatchedStatements=true
测试代码及结果:
1、插入操作:
insert方法:一条一条插入20条的话需要18秒;
saveBatch方法:加参数批量插入200条记录6秒; 不加参数批量插入20条记录8秒;
2、修改操作
updateById方法:一条一条的更新200条记录花费时间190秒;
updateBatchById方法:加参数批量更新200条记录70秒; 不加参数批量更新200条记录108秒;
3、修改操作
未添加#&rewriteBatchedStatements=true参数;批量修改200条记录,用时1829ms;
添加#&rewriteBatchedStatements=true参数;批量修改200条记录,用时1645ms;
4、批量查找
1、未添加#&rewriteBatchedStatements=true参数;批量修改200条记录,用时899ms
2、添加#&rewriteBatchedStatements=true参数;批量修改200条记录,用时612ms;
@SpringBootTest
@RunWith(SpringRunner.class)
public class PaperApplicationTests {
@Autowired
private DiseaseMapper diseaseMapper;
@Autowired
private DiseaseIServiceImpl diseaseIService;
//insert方法:一条一条插入20条的话需要18秒
@Test
public void contextInsert() {
List<Disease> entityList = new ArrayList<>(1000);
for (int i=1;i<20;i++){
Disease disease = new Disease();
disease.setCategory("鼻子" + i);
disease.setInformation("鼻子发炎11");
disease.setSearch1(0);
entityList.add(disease);
}
long startTime = System.currentTimeMillis(); //获取开始时间
for(Disease disease : entityList){
diseaseMapper.insert(disease);
}
long endTime = System.currentTimeMillis(); //获取结束时间
System.out.println("程序运行时间:" + (endTime - startTime) / 1000); //输出程序运行时间
// Disease disease = new Disease();
// disease.setCategory("鼻子1");
// disease.setInformation("鼻子发炎11");
// disease.setSearch1(0);
// int insert = diseaseMapper.insert(disease);
// System.out.println(insert);
}
// saveBatch方法:加参数批量插入200条记录6秒; 不加参数批量插入20条记录8秒
@Test
public void contextBatchInsert() {
List<Disease> entityList = new ArrayList<>(1000);
for (int i=1;i<200;i++){
Disease disease = new Disease();
disease.setCategory("鼻子" + i);
disease.setInformation("鼻子发炎11");
disease.setSearch1(0);
entityList.add(disease);
}
long startTime = System.currentTimeMillis(); //获取开始时间
boolean b = diseaseIService.saveBatch(entityList);
long endTime = System.currentTimeMillis(); //获取结束时间
System.out.println("程序运行时间:" + (endTime - startTime) / 1000); //输出程序运行时间
}
// updateBatchById方法:加参数批量更新200条记录70秒; 不加参数批量更新200条记录108秒
@Test
public void contextBatchUpdate() {
List<Disease> entityList = new ArrayList<>(1000);
for (int i=1;i<200;i++){
Disease disease = new Disease();
disease.setId(i);
disease.setCategory("眼镜" + i);
disease.setInformation("眼镜看不清");
disease.setSearch1(0);
entityList.add(disease);
}
long startTime = System.currentTimeMillis(); //获取开始时间
boolean b = diseaseIService.updateBatchById(entityList);
long endTime = System.currentTimeMillis(); //获取结束时间
System.out.println("程序运行时间:" + (endTime - startTime) / 1000); //输出程序运行时间
}
// updateById方法:一条一条的更新200条记录花费时间190秒
@Test
public void contextUpdate() {
// List<Disease> entityList = new ArrayList<>(1000);
long startTime = System.currentTimeMillis(); //获取开始时间
for (int i=1;i<200;i++){
Disease disease = new Disease();
disease.setId(i);
disease.setCategory("鼻子" + i);
disease.setInformation("鼻子发言啦");
disease.setSearch1(0);
diseaseMapper.updateById(disease);
}
long endTime = System.currentTimeMillis(); //获取结束时间
System.out.println("程序运行时间:" + (endTime - startTime) / 1000); //输出程序运行时间
}
//未添加#&rewriteBatchedStatements=true参数;批量修改200条记录,用时1829ms;
//添加#&rewriteBatchedStatements=true参数;批量修改200条记录,用时1645ms;
@Test
public void contextBatchDelete() {
List<Integer> arr = new ArrayList<>(200);
for(int i = 995; i <= 1193; i++){
arr.add(i);
}
long startTime = System.currentTimeMillis(); //获取开始时间
diseaseMapper.deleteBatchIds(arr);
long endTime = System.currentTimeMillis(); //获取结束时间
System.out.println("程序运行时间:" + (endTime - startTime) + "ms"); //输出程序运行时间
}
//1、未添加#&rewriteBatchedStatements=true参数;批量修改200条记录,用时899ms
//2、添加#&rewriteBatchedStatements=true参数;批量修改200条记录,用时612ms;
@Test
public void contextBatchSearch() {
List<Integer> arr = new ArrayList<>(200);
for(int i = 1194; i <= 1392; i++){
arr.add(i);
}
long startTime = System.currentTimeMillis(); //获取开始时间
diseaseMapper.selectBatchIds(arr);
long endTime = System.currentTimeMillis(); //获取结束时间
System.out.println("程序运行时间:" + (endTime - startTime) + "ms"); //输出程序运行时间
}
}
少年的志向,不应该是房子,他们应该伏案疾书,或为心中的梦想而挥洒汗水,畅想着自己未来光明的人生,少年的梦想,也不应该是生活,他们应该想要集齐七颗龙珠,或者幻想着拥有一颗皮卡丘。欢迎关注微信公众号<彭晓琪>,Java学习交流qq群(百人群):608827101
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报