这一年让我印象深刻的bug -- 让sql选择更合理的执行过程

1 业务场景

     客户需要一个报表统计工单的各种信息,于是我们利用公司报表平台做了一个报表导出功能。可是当我们准备上ver环境时测试反应报表导出虽然数据正确但性能不能达标,导出非常缓慢。于是我就开始分析报表sql。

2 问题分析

     相信有过开发经验的同学都知道,讲到分析sql立马会想到explain。于是我用explain分析了下sql结果如下
在这里插入图片描述
大多数人看到这里发现key这列已经使用索引并且ref为const了就觉得都是用是索引了那sql好像没啥好优化的,这时候就开始分析能不能业务逻辑或开发逻辑上进行优化。
     但是我们仔细看下26到33行rows这列你会发现虽然使用了索引但是这索引效率好像不大行,因为影响的行数都特别多。说明虽然使用了索引但是索引效率不太行啊。
      为啥索引效率不行呢?我们看下key这行他们使用的索引是 lcs_advice_trace_operate_type_IDX,我们去表看表发现lcs_advice_trace_operate_type_IDX是通过operate_type表字段建立的,实际上operate_type字段在表了只有5种情况,这个索引完全没有区分度。
在这里插入图片描述
      我们再来看看possible_keys这一列,发现其实有两个索引lcs_advice_trace_advice_no_IDX 和lcs_advice_trace_operate_type_IDX可以使用,而且分析表发现lcs_advice_trace_advice_no_IDX是一个非常有区分度的索引,因为lcs_advice_trace_advice_no_IDX是根据字段advice_no建立的,而advice_no在表中是一个唯一字段。
     分析到这里我们应该知道问题就是,mysql选择了一个没有区分度的索引,导致查询缓慢

3 解决办法

      既然是mysql选择了没有区分度的索引导致查询缓慢,那我们让mysql选择有区分度的索引就解决问题了,要改变mysql的执行计划有两个方法
      方法一:使用FORCE INDEX指定mysql使用哪个索引
在这里插入图片描述
      方法二:删除区分度不高的索引,显然索引lcs_advice_trace_operate_type_IDX完全没有区分度完全可以把它删除,让mysql只能选择索引lcs_advice_trace_advice_no_IDX。本例中我们删除lcs_advice_trace_operate_type_IDX后查询缓慢问题马上解决了

4 总结

  1. 我们要建立有效索引,对区分度不大的字段没必要建索引
  2. 我们要放让mysql走更有效的索引
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值