索引失效的7种情况
- 查询条件中有or,除非所有的查询条件都建有索引,否则索引失效
- like查询是以%开头
- 如果列类型是字符串,那在查询条件中需要将数据用引号引用起来,否则不走索引
- 索引列上参与计算会导致索引失效
- 违背最左匹配原则
- 全表扫描更快的意思。如果数据库预计使用全表扫描要比使用索引快,则不使用索引。
我们这边说的索引失效主要是为 复合索引
MySQL底层为B+树,我们需要了解B+树的底层查询原理
B+树底层查询是 二分查找
二分查找我们需要满足排序的有序性
举个例子:以下a,b 组成的复合索引
单独来看a,b;则a是有序的,b是无序的,但如果把a确定,可以观察到当a的值确定时,b的值是相对有序的,如下:
当 a = 1,b 为 1 ,2
当 a = 2,b 为 1, 4
当 a = 3,b 为 1, 2
重点:只有当 a 和 b 都有序时(要满足二分查找的条件),复合索引才会有效,(因为如果a确定的话,b的顺序也是相对有序的)
所以复合索引失效主要是体现在,条件不满足二分查找的条件(即破坏了有序性)
注意:索引失效并不代表索引不起作用,而是索引只起了一部分作用(这点很重要,主要体现在explain语句中查看索引时,不能去看是否key是否有索引,而是去看索引影响的rows的行数,demo中我会讲解)
Demo
1. 创建一个名为 test 的表,插入一部分数据
2. 创建一个复合索引:
- a和b的复合索引: test_index
3. 我主要分析以下三种情况,其他情况类似
- select a,b from test where a=2 and b>3;
- select a,b from test where a>2 and b>3;
- select a,b from test where a>2 and b=3;
情况一:
explain select a,b from test where a=2 and b>3;
row的影响行数为2,
当满足a=2条件下,有3条数据,而现在row的影响行数为2条数据,说明复合索引有效
原因:因为当满足a=2条件下时,b的3条数据在b+树中是相对有序的,所以复合索引有效
情况二:
select a,b from test where a>2 and b>3;
row的影响行数为6
如果复合索引成功的话,影响行数应该为4,而此时row为6,说明索引失效,复合索引只有 a>2(a大于2的有6条数据) 这个条件有效(即索引一部分有效)
原因:当a>2时,满足二分法有序性的条件,但b此时是不满足有序性的,如上图给的例子
情况三:
explain select a,b from test where a>2 and b=3;
row的影响行数为6
如果复合索引成功的话,影响行数应该为1,而此时row为6,说明索引失效,复合索引只有 a>2有效
原因:当a>2时,满足二分法有序性的条件,但b此时是不满足有序性的,如上图给的例子