前言:
在最近的工作中,分到几个慢接口优化的任务,这里记录一下慢接口优化的过程
系统方面:微服务系统
响应时间:13S(秒)
优化过程:
1. SkyWalking(链路追踪分析系统)
使用:追踪-->端点名称:(所需要分析的接口名)-->时间范围:(选择时间) -->搜索
说明:由于是微服务系统,业务的复杂性较高,所以我这边借用链路追踪工具来分析出这个接口中慢的原因(sql慢、第三方接口慢、feign接口慢....)
发现:通过使用链路追踪分析工具,我发现是一个批量更新的sql很慢,有11秒多
sql结果如下:
update TableA set delete_flag=1 where (aid=? and pad=? and status=? delete_flag=0) or (aid=? and pad=? and status=? delete_flag=0) or (aid=? and pad=? and status=? delete_flag=0) or (aid=? and pad=? and status=? delete_flag=0) or (aid=? and pad=? and status=? delete_flag=0) or (aid=? and pad=? and status=? delete_flag=0) or (aid=? and pad=? and status=? delete_flag=0) ......
2.确定sql慢
首次分析:这种sql一般是纯手写sql,此时我们需要梳理代码,并找到此sql
再次分析:再次分析代码,仔细分析sql的入参是什么,并联系上下文(尤其是上文)
查看mapper.xml文件中的sql:(哇哦,delete标签中是update语句,能这样写吗?不用怀疑自己去查)
<delete id="" parameteType ="java.util.List"> update TableA set delete_flag=1 where <foreach collection="list" item="item" separator="or" index="index"> (aid=#{item.aid} and pad=#{item.pad} and status=#{item.sad} and delete_flag=0) </foreach> </delete>
3.分析此条sql结果和相关的代码逻辑
sql发现:通过sql结果发现,OR拼接太多(这个是最直观的)。where条件有点多,这个几个字段是否添加了索引?
通过 show index from TableName,查看这个表的索引情况,通过发现只有主键id字段有索引
代码逻辑:使用了这样List<Map<String,Map>> list = new ArrayList<>(); 然后直接批量更新,通过观察这个map有很大可能是代表一个对象
4.总结出现的问题
根据上面的分析:没有使用索引,OR拼接太多,where条件太多,map代表一个对象
5.优化思路
方案一:能否再增加索引,来解决OR 和 where的问题?
虽然增加索引能够增加匹配效率,但是此时条件中有4个字段,在加上主键字段,已经是5个。我们知道一般情况下一张表的索引是不超过5个的(也就是说最多5个)
所以,此方案不合理
不合理的地方:A:增加索引,虽然可以解决目前的更新效率,但是时间一长,数据量增大,问题依然存在。
B:OR拼接太多的问题根本就没有解决
C:一个问题增加到5个索引字段,若后续字段还需增加索引,根据规定,无法在增加索引字段,后续问题无法解决
方案二:代码逻辑优化,试图利用主键进行批量更新
A:根据原代码逻辑构建出条件,进行查询,主要是获取主键
B:根据主键字段,进行批量更新
所以,此方案合理
标签:记录,接口,索引,flag,pad,sql,aid,优化,delete From: https://www.cnblogs.com/Life-QX/p/17039239.html