开心一笑
【跟我妈说这几天特别郁闷,心情糟透了。
我妈说:要不我给你拿钱你出去玩几天啊!
我立马笑颜逐开:“好啊好啊”!
妈:“开心了吧”!
我:“嗯嗯,妈,快点拿钱呀!”
妈:“你都开心了我还拿钱干啥!”
我。。。】
提出问题
真实项目中,批量插入数据性能优化???
解决问题
1.业务场景
1.1 业务描述
数据库有一张表(pm_testcase),客户有一份excel数据,里面有3+万条左右案例。现在需要解析excel里面的内容,对每条数据进行校验。比如:名称长度校验,编号校验,用户账号是否存在检验等等。然后封装成 List 集合,批量保存。
CREATE TABLE "public"."pm_testcase" (
"id" varchar(32) COLLATE "default" NOT NULL,
"code" varchar(50) COLLATE "default",
"name" varchar(200) COLLATE "default",
//....省略若干个字段
CONSTRAINT "pk_pm_testcase" PRIMARY KEY ("id")
)
WITH (OIDS=FALSE)
;
1.2 业务流程图
2.项目现状
2.1 问题一
在excel数据导入,循环 List 集合,进行校验时,存在大量的连接数据库操作。
//循环excel的每一行
for (int j = sheet.getFirstRowNum() + 1,len = sheet.getLastRowNum(); j <= len; j++) {
Row row = sheet.getRow(j);
if (row == null) continue;
if (StringUtils.isEmpty(getValue(row.getCell(6)))) resultBuffer.append("案例类型为空,");
//....省略其他校验操作...
//连接数据库
SysUser sysUser = sysUserService.findById(id);
}
2.2 问题二
直接批量保存3万多条数据。
List<PcsTestcase> pcsTestcases = new ArrayList<>();
// ......
//直接调用批量保存
this.batchCreate(pcsTestcases);
2.3 问题三
批量保存时,利用UUID生成工具,给主键设置Id。找出Hibernate的先查询后更新的机制触发,造成不必要的查询损耗。
List<PcsTestcase> pcsTestcases = new ArrayList<>();
PcsTestcase pcsTestcase = null;
for (int j = sheet.getFirstRowNum() + 1,len = sheet.getLastRowNum(); j <= len;j++) {
Row row = sheet.getRow(j);
if (row == null) continue;
pcsTestcase = new PcsTestcase();
//看这里,重要:这里在插入数据时,设置主键Id
pcsTestcase.setId(UUIDUtils.generate());
pcsTestcase.setPmMilestoneId(pcsMainTask.getId());
}
3. 解决方法
3.1 问题一解决方法
对于问题一,除了避免在 for 循环体内连接数据库外,我们可以利用 Map集合的缓存机制,把之后需要用到的数据加载到map集合中。比如:依次性查询出所有的用户数据等等,存放在Map集合中。
3.2 问题二解决方法
对于问题二,我们可以把所有数据,每500条进行一次批量保存操作,速度会比一次性批量保存好。具体如下:
if(j % 500 == 0 || j == len){
this.batchCreate(pcsTestcases);
pcsTestcases = new ArrayList<>();
}
3.3 问题三解决方法
对于问题三,由于Hibernate在进行插入时,会判断数据是进行插入还是进行更新。如果模型的主键不为空,查询数据后,再进行更新数据,否则,进行插入数据操作。因此,我们在进行插入操作时候,不要设置模型的主键,可以避免不必要查询消耗。
pcsTestcase.setId(UUIDUtils.generate());
基本的优化思路就是这样了,大功告成~~~
读书感悟
来自北宋名相寇准《六悔铭》,教人要及早觉悟悔改
- 六悔铭
官行私曲,失时悔。
富不俭用,贫时悔。
艺不少学,过时悔。
见事不学,用时悔。
醉发狂言,醒时悔。
安不将息,病时悔。
经典故事
【一教授与农民在火车上相对而坐,无聊之际。教授说:我出一道题,你若不知,给我5元,如果你出一道题,我若不知,给你500元如何?农民同意。教授问:月亮距地球多远?农民一言不发递给教授5元。农民问:上山三条腿,下山四条腿,是什么动物?教授苦思无解,无奈给农民500元。农民接过钱准备睡觉。教授追问:上山三条腿,下山四条腿究竟是什么动物?农民一言不发递给教授5元钱,然后睡觉了。低学历高智商,太可怕了!这就是许多没学历的人能成为老板,首富的原因。】
大神文章
【1】【Java/JDBC.ORM】 jdbc插入大量数据时优化处理
【2】Hibernate批处理操作优化 (批量插入、更新与删除)
【3】用Java向数据库中插入大量数据时的优化
其他
如果有带给你一丝丝小快乐,就让快乐继续传递下去,欢迎点赞、顶、欢迎留下宝贵的意见、多谢支持!