记录一次查询接口优化过程
创始人
2024-01-27 23:30:14
0

前几天业务方反馈有一个接口查询时间,超过了1.5秒,不能忍了,让我看看,我看了下逻辑,对其中的一些逻辑进行了优化,也比较简单,这里做一个记录。

1.第一个改造就是

List callSaleInfoDtos = CallSaleInfoDto.fromEntity(callSaleInfoList, new CallSaleInfoDto());

这个方法本质上还是使用了
BeanUtils.copyProperties(dto, entity);
这个方法耗时特别长,200个数据耗时将近要1秒左右,后来改成 Lambda形式,200个时间缩短到10毫秒左右

List callSaleInfoDtos = callSaleInfoList.stream().map(callSale -> {CallSaleInfoDto dto = new CallSaleInfoDto();dto.setId(callSale.getId());dto.setUserId(callSale.getUserId());dto.setName(callSale.getName());dto.setProperty(callSale.getProperty());dto.setPrivateNum(callSale.getPrivateNum());dto.setBindTel(callSale.getBindTel());dto.setWorkPhone(callSale.getWorkPhone());dto.setTeam(callSale.getTeam());dto.setLogin(callSale.getLogin());dto.setBusy(callSale.getBusy());dto.setDeleted(callSale.getDeleted());dto.setSupplier(callSale.getSupplier());dto.setAxbSupplier(callSale.getAxbSupplier());dto.setCreateTime(callSale.getCreateTime());dto.setUpdateTime(callSale.getUpdateTime());dto.setBusyChangeTime(callSale.getBusyChangeTime());dto.setRrcCno(callSale.getRrcCno());return dto;}
).collect(Collectors.toList());

还有一个:

for (int i = 0; i < callSaleInfoDtos.size(); i++) {List callSaleDetailList = callSaleService.getDetailByCCid(callSaleInfoDtos.get(i).getId());callSaleInfoDtos.get(i).setCallSaleDetailList(callSaleDetailList);
}

这里遍历了每一个值,然后去查询数据库,这样如果有200个数据,就会跟数据库有200次的IO交互,对数据库的压力很大,并且耗时也很大,改成了下面这种

List idList = callSaleInfoDtos.stream().map(s -> s.getId()).collect(Collectors.toList());
List callSaleDetailList = callSaleService.getDetailByCcIds(idList);
if (CollectionUtils.isEmpty(callSaleDetailList)) {return Response.ok(Collections.emptyList());
}
Map> callSaleDetailMap = callSaleDetailList.stream().collect(Collectors.groupingBy(CallSaleDetail::getCcId));
for (int i = 0; i < callSaleInfoDtos.size(); i++) {List detailList = callSaleDetailMap.getOrDefault(callSaleInfoDtos.get(i).getId(), Collections.emptyList());callSaleInfoDtos.get(i).setCallSaleDetailList(detailList);
}

改成了上面这种,首先拿到id列表,然后再数据库中使用in 查询一次数据库,将结果再使用Lambda 转换成Map,最后再根据map去匹配,在set进去最终的结果。

这里要注意的一点是 mysql对 in 也有要求,有的时候也会不走索引,但是这里最多就几百个,并且表中的总数据也就2000左右,问题不大。

结论:

1、改造前这个接口平均1.5秒,改造后 平均相应300毫秒,提升了5倍

那么问题来了,使用Lambda为啥会这么快呢?这值得研究一下:
java8特性lambda基本原理及性能分析:https://blog.csdn.net/heima201907/article/details/104983485
有时间看一下这篇文章,今天先写到这里

相关内容

热门资讯

保存时出现了1个错误,导致这篇... 当保存文章时出现错误时,可以通过以下步骤解决问题:查看错误信息:查看错误提示信息可以帮助我们了解具体...
汇川伺服电机位置控制模式参数配... 1. 基本控制参数设置 1)设置位置控制模式   2)绝对值位置线性模...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
表格中数据未显示 当表格中的数据未显示时,可能是由于以下几个原因导致的:HTML代码问题:检查表格的HTML代码是否正...
本地主机上的图像未显示 问题描述:在本地主机上显示图像时,图像未能正常显示。解决方法:以下是一些可能的解决方法,具体取决于问...
表格列调整大小出现问题 问题描述:表格列调整大小出现问题,无法正常调整列宽。解决方法:检查表格的布局方式是否正确。确保表格使...
不一致的条件格式 要解决不一致的条件格式问题,可以按照以下步骤进行:确定条件格式的规则:首先,需要明确条件格式的规则是...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...