索引失效及联合索引生效总结

索引失效的场景:

  1. like 以%开头,索引无效;当like前缀没有%,后缀有%时,索引有效。

  2. or语句前后没有同时使用索引。当or左右查询字段只有一个是索引,该索引失效,只有当or左右查询字段均为索引时,才会生效。

  3. 组合索引,不是使用第一列索引,索引失效。

  4. 数据类型出现隐式转化。如varchar不加单引号的话可能会自动转换为int型,使索引无效,产生全表扫描。

  5. 在索引列上使用 IS NULL 或 IS NOT NULL操作。索引是不索引空值的,所以这样的操作不能使用索引,可以用其他的办法处理,例如:数字类型,判断大于0,字符串类型设置一个默认值,判断是否等于默认值即可。

  6. 在索引字段上使用not,<>,!=。不等于操作符是永远不会用到索引的,因此对它的处理只会产生全表扫描。 优化方法: key<>0 改为 key>0 or key<0。

  7. 对索引字段进行计算操作。

  8. 在索引字段上使用函数。

  9. 当全表扫描速度比索引速度快时,mysql会使用全表扫描,此时索引失效。

 

组合索引的使用效果的总结

1.组合索引多字段是有序的,并且是个完整的BTree 索引,有最左原则

多列索引是先按照第一列进行排序,然后在第一列排好序的基础上再对第二列排序,如果没有第一列的话,直接访问第二列,那第二列肯定是无序的,直接访问后面的列就用不到索引了。

搜索需要从根节点出发,上层节点对应靠左的值,搜索需要从根节点出发,否则不从根节点出发,后面的节点对应下层的值,依旧是乱序的,需要遍历,所以索引就失效了,所以有最左原则。

2.组合索引的使用:

例如组合索引(a,b,c),组合索引的生效原则是 

从前往后依次使用生效,如果中间某个索引没有使用,那么断点前面的索引部分起作用,断点后面的索引没有起作用;

比如

where a=3 and b=45 and c=5 .... 这种三个索引顺序使用中间没有断点,全部发挥作用;

where a=3 and c=5... 这种情况下b就是断点,a发挥了效果,c没有效果

where b=3 and c=4... 这种情况下a就是断点,在a后面的索引都没有发挥作用,这种写法联合索引没有发挥任何效果;

where b=45 and a=3 and c=5 .... 这个跟第一个一样,全部发挥作用,abc只要用上了就行,跟写的顺序无关

组合索引使用判断:

(0) select * from mytable where a=3 and b=5 and c=4;

abc三个索引都在where条件里面用到了,而且都发挥了作用

(1) select * from mytable where c=4 and b=6 and a=3;

这条语句列出来只想说明 mysql没有那么笨,where里面的条件顺序在查询之前会被mysql自动优化,效果跟上一句一样

(2) select * from mytable where a=3 and c=7;

a用到索引,b没有用,所以c是没有用到索引效果的

(3) select * from mytable where a=3 and b>7 and c=3;(范围值就算是断点)

a用到了,b也用到了,c没有用到,这个地方b是范围值,也算断点,只不过自身用到了索引

(4) select * from mytable where b=3 and c=4;

因为a索引没有使用,所以这里 bc都没有用上索引效果

(5) select * from mytable where a>4 and b=7 and c=9;

a用到了 b没有使用,c没有使用

(6) select * from mytable where a=3 order by b;

a用到了索引,b在结果排序中也用到了索引的效果,前面说了,a下面任意一段的b是排好序的

(7) select * from mytable where a=3 order by c;

a用到了索引,但是这个地方c没有发挥排序效果,因为中间断点了,使用 explain 可以看到 filesort

(8) select * from mytable where b=3 order by a;

b没有用到索引,排序中a也没有发挥索引效果

你可能感兴趣的:(mysql)