【详解】面试必问:MySQL索引为什么会失效?最左匹配原则中间有间隙,为什么索引不会被命中?%开头索引为什么失效?范围查询索引为什么会失效?

首先看看索引的基本操作、索引的底层原理,先看这2篇文章:

【详解】MySQL索引的基本操作,索引(主键索引,普通索引,组合索引,唯一索引)_CodingLJ-CSDN博客

【详解】面试必问:MySQL索引底层原理(基于B+Tree)_CodingLJ-CSDN博客


1、基础知识

知识补充:

        多路搜索树是有序的,这个是数据结构中树的部分内容。以二叉搜索树为例,说下搜索树的特点,根节点的值始终大于左孩子的值,根结点的值始终小于右孩子结点的值;当然左右孩子也有这样的规律。

        索引失效的情况主要是针对联合索引(组合索引)。我们知道,MySQL底层是B+树(多路搜索树)。普通的B+Tree是一个结点只有一个值,联合索引对应的多路搜索树的结点是多个键值。下图是联合索引的B+Tree的数据结构图:

         从本质上说,联合索引也是一棵B+Tree,不同的是,联合索引的键值数量是大于等于2的。接下来看两个整型列组成的联合索引,假设两个键值的名称分别为a、b,如上图。我们可以发现,键值都是排序的,通过叶子结点可以逻辑上顺序读出所有数据。即(1,1)、(1,2)、(2,1)、(2,4)、(3,1)、(3,2)。数据是按照(a,b)的顺序进行存放。

        因此,对于查询SELECT *  FROM TABLE WHERE a = xxx AND b = xxx;显然是可以使用(a,b)联合索引。对于单个的a列SELECT *  FROM TABLE WHERE a = xxx;显然也可以使用(a,b)联合索引。但是对于b列的查询SELECT * FROM TABLE WHERE b = xxx;显然不可以使用B+树的索引;可以发现叶子结点上的b值1,2,1,4,1,2是无序的,因此对于查询b列使用不到(a,b)索引。结果就是全文索引来查 WHERE b = xxx的情况。

        MySQL底层做了优化,对第二个键值也做了排序。也就是在a值相等的情况下,b值是有序的;比如:当a=1的时候,b值从左到右为1,2;当a值为2的时候,b值为1,4。平时我们在写SQL语句的时候,如果第一个字段相同的情况下,再使用第二个字段做排序。

以上是解决索引为什么失效的基础知识,必掌握。

以上是解决索引为什么失效的基础知识,必掌握。

以上是解决索引为什么失效的基础知识,必掌握。

2、索引为什么会失效?

        使用索引进行查询的时候必须遵循的是最左匹配原则。所谓最左匹配原则,就是查询的条件属性必须从索引的最左边开始,中间不能有间隙。要不然不会被命中。为什么不会被命中呢?还是回到多路搜索树说下。

分析一:也就是最左匹配原则有间隙为什么索引失效?为什么不会命中?

SELECT *  FROM TABLE WHERE a = xxx AND b = xxx

 索引失效原因:

(a,b):a是有序的,在a相等的情况下b是有序的。单单看b是无序的如果跳着查b的话,就不遵循最左前缀法则,多路搜索树是顺序的树a是不参与查询的,这样b是无序的,那么此时就会全表扫表。此时是一个无序的b+树,就找不到需要的这个值,这种情况下就用不到索引,只能进行全表扫描。整个搜索树是有序的,无序的话没办法从二分查找法找找出来

分析二:

select * from table where a > 1 and b = 1

 索引失效原因:

(a,b):当出现 > < 范围查询的时候,索引会失效。a > 1,b = 1结果是(2,1)(2,4)(3,1)(3,2)。b值是无序的。此时是一个无序的b+树,就找不到需要的b这个值,这种情况下就用不到索引,只能进行全表扫描。

分析三:where a like "%%",以%为开头的查询条件索引会失效。

like  "%1%"  "%1",是不走索引的
“1%”需要查询的数据在左边,这种是前缀
“%1”需要查询的数据在右边,这种是后缀
字母作比较

索引失效原因:

比如,“%a”,"%a%":这个时候不是前缀法则了,它是去查找以a为结尾的字符串,这个是没有顺序的。在没有顺序的前提下去二叉树上查找数据,肯定是查找不到的就用不到这个索引

小结:

        上面举了3个索引失效的例子,以及失效的原因。基本上和索引底层B+Tree底层数据结构有着千丝万缕的关系。

        分析的时候主要从多路搜索树的底层B+树的特点,以及命中的条件来回答,B+树是有顺序的,索引失效没有循序B+Tree的顺序法则,导致查询的是无序元素,最终全表扫描,索引失效。

具体问题具体分析,围绕B+Tree底层展开。

以上就是索引为什么失效的原因!

猜你喜欢

转载自blog.csdn.net/Sunshineoe/article/details/121344903