索引不是每次都可以生效的,如果我们操作不对,那么很有可能是走全表扫描而不是走的索引,Explain 中的 possible_key、key_len 以及 key 参数都可以分析我们的 SQL 语句是否用到了索引。
以下情况将会导致索引失效
- 在索引字段上使用not,<>,!=。不等于操作符是永远不会用到索引的,因此对它的处理只会产生全表扫描。 优化方法: key<>0 改为 key>0 or key<0。
- like 以%开头,索引无效;当like前缀没有%,后缀有%时,索引有效。
- 对索引字段进行计算操作、字段上使用函数,比如 pow(id,2) 对 id 做平方这种函数表达式或者 id+1,也不会用到索引
- or语句前后没有同时使用索引。当or左右查询字段只有一个是索引,该索引失效,只有当or左右查询字段均为索引时,才会生效
- 联合索引满足最左前缀原则,如:index_abc 联合索引在查询条件 b<10 and c <10,没有用到索引?而 a<10 and c <10用到了
- 联合索引中即使满足最左前缀原则,但是第一个条件带了范围查询,那么索引访问类型会降级(如上一条中的<换成=可使用ref类型索引,但使用< 则只能使用index 类型)
- 存在索引列的数据类型隐形转换,则用不上索引,比如列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引
- 在索引列上使用 IS NULL 或 IS NOT NULL操作。索引是不索引空值的,所以这样的操作不能使用索引,可以用其他的办法处理,例如:数字类型,判断大于0,字符串类型设置一个默认值,判断是否等于默认值即可。
- 如果 MySQL 估计使用全表扫描要比使用索引快,则不使用索引
以上都可以使用 Explain 进行测试是否用到了索引。
