order by,limit,where 索引的优先级

问题引入
线上bug出现慢sql,排查语句为

SELECT
  *
FROM
  表1
WHERE
  (  
  c1=?
  ,c2=?
  ,c3=?
  ,c4=?
  ,c5>?
  )
ORDER BY
  c5 DESC,
  c6 DESC
  limit 1

索引情况是 两个索引
索引a c1_c2_c3_c4_c5
索引b c4_c6
explain 索引走的第二个,产生疑问
尝试解决 去掉limit走索引a,变更 orderby后的字段不命中索引 走索引a
猜测结论:同时使用WHERE,ORDER BY,limit,且WHERE,ORDER BY命中相同的索引,会优先使用

继续尝试其他可能
WHERE后删除c1,其他不变,命中索引b
WHERE后删除c1,删除limit,无索引命中
WHERE后删除c1,ORDER BY删除c6,无索引命中
结论:使用limit时,会去ORDER BY后面找是否有索引,有并且字段全部命中会使用索引。

继续尝试其他可能
WHERE后不变,删除limit,命中索引a
结论:
正当我信心满满觉得摸出规律的时候,我改变了一下c1字段的值,发现使用的索引变成了索引 c1_c2_c3_c其他

最终结论:没结论,看mysql心情

但可以看出来的是 orderby 后面会用到索引,但必须用到limit且命中组合索引的所有字段

现在再来看应该是where后面的索引失效了,然后走了orderby后的索引,至于失效原因没有找到,但确实和条件值有关系,并且在改掉limit后字段不走索引后,where后的字段又神奇的走了索引a,多次查询发现,大多数查询用的索引都是c,

请教同事后,
原因是
SELECT
*
FROM
表1
WHERE
(
c1=?
,c2=?
,c3=?
,c4=?
,c5>?
)
捞出的数据过多有7000条,但是你的limit为1,mysql优化器认为数据量太大,即走了orderby后面的
简单验证:修改limit为3500,走了索引a符合预期,结论成立

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值