前言:
此时各位老铁们对“sql优化如何避免全表扫描”大致比较注重,看官们都想要剖析一些“sql优化如何避免全表扫描”的相关文章。那么小编也在网摘上搜集了一些有关“sql优化如何避免全表扫描””的相关内容,希望姐妹们能喜欢,你们一起来学习一下吧!也是很巧合,之前遇到过一次情况,一条SQL,根据时间范围查数据,但有时候速度很快,有时候速度就慢。
第一反应是没有设置索引,但开发人员告诉我已经设置了二级索引,查询的速度依然有快有慢。
通过explain解析,发现同一条SQL,时间范围不一样,有的使用了索引,有的全表扫描。
当时我都懵逼了!
经过查询,发现一种说法是当查询的数据量超过全表的30%,就不再走索引,而直接全表扫描。
经过排查,我们的情况恰好符合,如果某一周数据约小于全表数据的30%时,走索引,反之全表扫描。
当时临时给出的解决办法就是把数据缓存,要慢也就是第一次慢,可以忍受。也想过用覆盖索引,但是要查询的字段太多了,不可能搞个那么大的索引。
但为什么产生这种情况,没找到答案,后来一直断断续续地关注这个问题,现在发现了一个能说服我自己的解答:
先说一下,这个阈值不一定是30%,也可以是别的数。
简单地说,就是MySQL的优化器一旦认为走索引的代价高于全表扫描,就直接扫全表。这个结论可能反常识,因为我们一直听说的就是索引提高查询性能。
这里涉及两个因素:
1、如果走二级索引查询,步骤就是:二级索引--主键索引,这就是回表查询。
2、硬盘随机I/O的性能远低于顺序I/O。
所以如果你的查询数据量大到一定程度,MySQL认为回表查询的随机I/O代价大于顺序I/O全表扫的情况下,将放弃走索引。