调了个方法导致接口变慢好多,真实原因有点坑。

前言

这篇文章是按照我的记忆梳理的,然后解决方法其实很简单,主要是梳理一下当时的排查思路,所以请大家多多指教。错误之处或表述不清楚的地方,欢迎评论指出或建议,感谢。

背景

事情发生在一个正常的下午,领导对我说:有项目组汇报说一个创建的接口变的比较慢,让我尽快排查一下。我一听,这个功能不是我写的,心里首先放松一下,那就排查吧!

验证线上

首先,当然是和领导确认,什么情况下,访问这个接口慢,因为有时候可能在某个特殊的场景下才会导致此类问题,或者是偶发情况,确定了这一点,也方便排查,然后我就按照领导说的,找到所属的数据页面,进行同样的操作。发现果然比较慢(这是我工作中学到的,不管别人怎么说,自己验证一遍),F12看了下,返回时间差不多快2s了,这个速度确实是有点慢的,因为这个添加的处理逻辑按理来说是不复杂的,不应该这么慢。

本地排查

接下来,就是排查的步骤,首先本地先启动一下,连接测试库看看是否有慢的问题,如果本地也慢,就比较方便一些,可以通过日志来打印每一部分花费的时间(我一般用StopWatch类),就可以知道哪里慢了。但是遗憾的是本地没有复现这种情况。

代码排查

既然无法复现,就只能看代码了,对比了下涉及到这个文件的提交记录,大概伪代码如下:

java 复制代码
...
...
String name = xxxService.getMember(name);
...
Project project = prjService.getProject(code);
...
project.getProjectId();
...
...

看见的第一眼,我直接忽略了这一段,觉得没啥问题啊,然后事实证明,事出反常必有妖。

最终原因

其实慢的原因就是我直觉忽略了的这一段代码中的Project project = prjService.getProject(code);,当我点进去后我才发现,里面别有洞天,我没法给大家复制代码,还是给大家一个伪代码:

java 复制代码
....
Project project = prjDao.getObject(code);
String pId = project.getProjectId();
List<Task> list = prjDao.queryTaskList(pId);
for (Task task : list){
    String taskId = task.getTaskId();
    Work w = prjDao.getObject(taskId);
    ....
    s = s.apend(w.getName());
}
project.setExtend(s);
....

以上代码存在的问题主要就是在for循环中进行对数据库的查询,如果list的长度很长的话,就会导致查询慢的问题,当时发现的时候真的是无语了,你如果有扩展,可以在方法中进行清晰的标识(比如:queryprojectExtend),并且代码也不必这么写,可以提取所有的taskId到一个list中,然后作为参数进行查询。

另外还有一个坑的点就是,其实原来的人调用这段方法本身其实就是为了拿一个project.getProjectId();,所以完全可以另外写一个简单获取的方法即可。

解决并验证

因为知道了原因,所以从数据库找了数据比较多的一个来进行复现,果然复现成功,也证明了问题就是出在这里。 首先把代码进行修复,修复后的伪代码如下:

java 复制代码
....
Project project = prjDao.getObject(code);
String pId = project.getProjectId();
List<Task> list = prjDao.queryTaskList(pId);
List<String> idList = list.getIdLIst(list);
List<Work> works = prjDao.queryObjectsByIds(idList);
for (Work task : list){
    s = s.apend(w.getName());
}
project.setExtend(s);
....

以上虽然也使用了for循环,但是内部只是做了字符串的拼接,也可使用Stream,会更简洁。 更改完后,继续测试该接口,发现是正常的。

思考总结

其实这次的问题很简单,没有涉及到高大上的一些问题来调整,要避免其实也很简单,调用其他人写的方法时,大概点进去观察一下。写方法的时候多想一下,是否会造成查询慢的问题,就可以了。

  • for循环查询这种情况,尽量避免。
  • 调用他人方法时需要知道内部大概的逻辑,切勿望文生义。
  • 不要想当然,觉得没问题就不排查。

致谢

感谢你的耐心阅读,如果我的分享对你有所启发或帮助,就给个赞呗,很开心能帮到别人。

相关推荐
uhakadotcom39 分钟前
AI搜索引擎的尽头是电商?从perplexity开始卖货说起...
前端·人工智能·后端
uhakadotcom42 分钟前
Java中的代码简化技巧:让开发更轻松
后端
张声录11 小时前
使用client-go在命令空间test里面对pod进行操作
开发语言·后端·golang
新智元2 小时前
AI卷翻科研!DeepMind 36页报告:全球实验室被「AI科学家」指数级接管
人工智能·后端
Adolf_19932 小时前
Django 自定义路由转换器
后端·python·django
ᝰꫝꪉꪯꫀ3613 小时前
JavaWeb——Mybatis
java·开发语言·后端·mybatis
机器之心3 小时前
跨模态大升级!少量数据高效微调,LLM教会CLIP玩转复杂文本
人工智能·后端
爱上语文4 小时前
Http 响应协议
网络·后端·网络协议·http
Smilejudy4 小时前
三行五行的 SQL 只存在于教科书和培训班
后端·github
爱上语文4 小时前
Http 请求协议
网络·后端·网络协议·http