前言
hello,大家好,最近开发项目版本迭代,秀总也是遇到几个关于接口响应慢的问题。针对性我做一下分析过程和总结
一、查询响应12秒分析
问题描述
首先一个查询,这个接口将近一千多行,外面有一个循环,然后里面又有一个循环,循环里面又有一个lambda表达式,然后下面又有一堆判断。我是怎么诊断到这一个代码快呢!
分析
-
1、屏蔽自己代码块(节省9秒)
首先我诊断这个接口是老接口改造,既然以前没有出现问题,现在出现问题,那肯定就是我写的那一块出了毛病,然后我将我写的核心逻辑代码块屏蔽了一下。结果省了9秒。 -
2、进一步分析
到了这一步,其实知道大概那个代码块,其实结果还没完,因为没找到核心代码行数以及解决。屏蔽肯定不现实,因为逻辑还是要走的。 -
3、精准找出代码块
于是我针对当前代码块大的代码块屏蔽。结果好家伙。发现这行代码花了7秒,而且这个代码块就做了一件事,如果有值就执行下面逻辑。于是我在想,正肯定需要移到最外层代码块那是不是这里吗逻辑都不用执行了 -
4、迁移代码块
于是我就将代码块迁移外面做处理,这样不用每次循环都执行这一段逻辑。
List<String> relationIdList = new ArrayList<>();
for (Integer productId : productIds) {
//Integer productId = projectVo.getProductModelId();
//根据机型 取得relationId(耗时6秒)
relationIdList = relationsByProductIds.stream()
.filter(res -> Objects.equals(Integer.valueOf(res.get("productModelId").toString()), productId))
.map(item -> item.get("relationId").toString()).filter(StringUtils::isNotBlank)
.collect(Collectors.toList());
}
然后我在调用刚刚方法哪里加了个判断,假如没数据,都不用走下面逻辑以及后面逻辑
- 5、结果
最终结果省了7秒,最终4秒左右响应了。虽然我这种非常笨,但是也是挺有效的。就是重启有点浪费时间了。
思考
所以针对查询我做了几个总结
1、查询时候循环太多,建议在循环体内查询啊、操作啊能迁移出去就迁移【循环体】
2、操作之类,建议先装到集合,然后循环体批量处理【批量处理】
3、循环时候达到自己的目的,建议能break就break【循环体】
4、能异步处理就异步处理【异步】
5、假如sql问题就涉及到sql优化,例如索引、慢查询、join过多、尽量使用exsit、子查询、缓存等方案处理【sql】
6、锁设计不合理