sql优化,关于联合索引某个中间字段使用>(大于)号,导致后面索引失效的理解(继续上次的补充)

c1 c2 c3 c4联合索引,安次顺序建立。
select * from c1=1 and c2=2 and c3>3 and c4=4
这个sql字段走索引的只有c1 c2 c3
为什么c4失效。
之前纠结于底层的数据结构,但是思维混乱。现在用英文字段作一个比喻。
字段都用过,我们都用来查单词。
字典的顺序就是我们查找某个单词,先看哪个开头,比如A开头,这样BCDEF这些对应的单词全都排除不用看了。然后看第二个字母比如是B开头,那么一样的ACDEFG这些都不用看了。只看AB…开头的这些单词就可以了。这就叫走索引。
现在出现c3>3,相当于让我们查找AB开头的单词,这个单词的第三个字母有一个范围,这个范围就是BCDEFG(这里只是打个比方),那么没关系,第三个字母依然有效,依然走了索引。但是为什么第四个字母就没有走索引了呢?
因为如果不是c3>3,而是c3=3,那么问题简单了,我们再用第四个字母看的时候,就不是从一个范围里面查找c4=4这个值了。而是从原来c3=3的索引路线找出来值,在这条路线只有c3=3,而没有c3=4 c3=5 c3=6…这些东西了。
这个没问题,c4是走索引了,你看看索引的结果,这就是原本的索引结构。没有任何争议。
可是现在是c3>3,也就是c3=4 c3=5 c3=6…很多可能,现在再来一个c4=4,这个条件的取值范围由原来的c3=3这条路线转成了 c3=3 这一条路线,转成了多条路线,因此这个没有走索引。我们知道索引的结构是只有一条路线的,如果某处由一条路线转成了多条,那么自然就是索引路线断了,断了就没有走索引了。

那么没有走索引,走的是什么呢?
没有走索引,也没有走全表扫描。走的是通过c1=1   c2=2   c3=3定位到的数据集的所有c4列的数据行。这个数据行显然比原先的数据少的多,当然不算是全表扫描了。

因此,无法避免的话,我们还是尽量让尽可能多的字段走索引,这样尽可能多的过滤掉无用的数据。

你可能感兴趣的:(sql优化,关于联合索引某个中间字段使用>(大于)号,导致后面索引失效的理解(继续上次的补充))