龙空技术网

查询的数据量超过阈值,不走索引直接全表扫描

Java个人学习心得 162

前言:

此时各位老铁们对“sql优化如何避免全表扫描”大致比较注重,看官们都想要剖析一些“sql优化如何避免全表扫描”的相关文章。那么小编也在网摘上搜集了一些有关“sql优化如何避免全表扫描””的相关内容,希望姐妹们能喜欢,你们一起来学习一下吧!

也是很巧合,之前遇到过一次情况,一条SQL,根据时间范围查数据,但有时候速度很快,有时候速度就慢。

第一反应是没有设置索引,但开发人员告诉我已经设置了二级索引,查询的速度依然有快有慢。

通过explain解析,发现同一条SQL,时间范围不一样,有的使用了索引,有的全表扫描。

当时我都懵逼了!

经过查询,发现一种说法是当查询的数据量超过全表的30%,就不再走索引,而直接全表扫描。

经过排查,我们的情况恰好符合,如果某一周数据约小于全表数据的30%时,走索引,反之全表扫描。

当时临时给出的解决办法就是把数据缓存,要慢也就是第一次慢,可以忍受。也想过用覆盖索引,但是要查询的字段太多了,不可能搞个那么大的索引。

但为什么产生这种情况,没找到答案,后来一直断断续续地关注这个问题,现在发现了一个能说服我自己的解答:

先说一下,这个阈值不一定是30%,也可以是别的数。

简单地说,就是MySQL的优化器一旦认为走索引的代价高于全表扫描,就直接扫全表。这个结论可能反常识,因为我们一直听说的就是索引提高查询性能。

这里涉及两个因素:

1、如果走二级索引查询,步骤就是:二级索引--主键索引,这就是回表查询。

2、硬盘随机I/O的性能远低于顺序I/O。

所以如果你的查询数据量大到一定程度,MySQL认为回表查询的随机I/O代价大于顺序I/O全表扫的情况下,将放弃走索引。

标签: #sql优化如何避免全表扫描 #数据库索引可以避免全表扫描 #mysql查询大于日期