性能优化:记一次批量新增&修改接口优化思路

优化前的代码

之前的代码大概如下,优化前要执行15分钟

1.	for(List dto : dtoList) {
2.		entity = dao.getByNameAndType(dto.getName(), dto.getType());
3.		if(null == entity){
4.			entity = new Entity();
5.		}
6.		BeanUtil.copyProperties(entity, dto);
7.		dao.save(entity);
8.	}

 上面的代码第一眼看上去并没什么问题,但是当要修改的dtoList有几千个的时候,就会很慢了!下面分析一下
 1)第2行,会发起1次数据库请求
 2)第6行,由于项目中用的是JPA,所以save的时候,会先判断id是否为null,为null则新增;如果不为null,还要发起一次查询请求,查看id是否真的存在,如果存在则修改;否则新增。这样子的话就相当save一条数据要发起2次请求。
 总的来说数据库请求就是3*n的时间复杂度

优化的思路

核心思路:尽可能的减少数据库连接的次数
具体方法:
1.一次性查询需要的数据,对于查询条件建立索引
2.对于要新增的,拼sql,一次性insert into values (), ()…
3.对于要修改的,拼sql,一次性update xxx set xxx=xxx;update xxx set xxx=xxx;并且修改之前先判断一下dto跟数据库的字段是否真的有变化,有变化才发请求

优化后的代码

优化后执行20秒,总的来看,优化过后的数据库请求就是3n的时间复杂度

// 一次性查询所有需要的记录,如果可以,查询缓存更好
querySql = new StringBuilder();
sql.append("select xxx, xxx from dtoTable ");
sql.append("where")
for(dto : dtoList){
	// 建立 name,type的联合索引
	sql.append("(name = " + dto.getName + " and type = " + dtp.getType+ ") or")
}
entityList = dao.find(querySql);

// dto具体要新增还是修改,分一下类
List addList = new ArrayList();
List updateList = new ArrayList();
for(List dto : dtoList) {
	entityList.stream.filter(条件).toList().getOne();
	if(entityList.size != 0){
		entity = entityList.get(0);
		// 根据业务比较一下,真正改变了才修改数据库
		if(!equal(entity, dto)){
			updateList.add(dto);
		}
	} else {
		addList.add(dto);
	}
}

// 批量新增
insertSql = new StringBuilder();
insertSql.append("insert into table(xxx, ooo, jjj) ");
insertSql.append("values  ");
for(dto : addList){
	insertSql.append("(xxx=xxx, ooo=ooo, jjj=jjj), ")
}
dao.execute(insertSql);

// 批量更新
updateSql = new StringBuilder();
for(dto : addList){
	updateSql.append("update table set xxx=xxx, ooo=ooo, jjj=jjj where id=xxx; ")
}
dao.execute(updateSql);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

我叫985

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

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

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

打赏作者

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

抵扣说明:

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

余额充值