MySQL索引失效的场景

85 阅读3分钟

“携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情

针对大数据量检索的场景,如果不加索引,一般响应时间都会很长。但是,加了索引,也有可能会出现查询速度并没有提升的情况,还是没有走索引。这种情况下可以使用explain命令查看sql语句。如果key值为null,说明并没有使用索引进行查询。

(整理了一下网上搜索到的场景,做个记录。)

MySQL索引失效的场景

1、字段类型不匹配导致的索引失效

进行SQL数据查询的时候,where条件字段类型与实际表中字段类型不匹配的时候,Mysql会进行隐式的数据类型转换,而类型转换会使用到内置函数,导致在进行数据查询的时候并没有使用索引。

2、被索引字段使用了表达式计算

在where中条件使用了条件表达式的时候,数据表中的索引就失效了,实际是因为Mysql需要将索引字段取出来之后再进行表达式的条件判断,因而进行了全表扫描,导致索引失效。

3、索引字段使用了内置函数

索引字段实际上是依赖于整个B+索引树的遍历,而索引树的遍历又依赖于索引树底层叶子节点的有序性。索引保存的是索引列的原始值,如果经过函数计算,Mysql的解释器无法判断计算后的索引在原来的索引树上是否可以被索引到,因此它就直接放弃使用索引查询了。

4、like使用了%x模糊匹配

使用左模糊匹配以及左右模糊匹配都会导致索引失效,但是使用右模糊匹配,还是可以走索引查询的。 由于B+树按照索引值进行排序的,实际是按照最左前缀进行比较,而使用了%作为最左前缀,Mysql无法判断其有序性,因此只能进行全表扫描查询。

5、索引字段不是联合索引字段的最左字段

如果数据库表中有联合索引的话,我们在SQL查询语句中使用的索引字段又不是联合索引的最左字段,那么就会导致索引失效。

6、or分割的条件,如果or左边的条件存在索引,而右边的条件没有索引,不走索引

因为 OR 的含义就是两个只要满足一个即可,因此只有一个条件列进行了索引是没有意义的,只要有条件列没有进行索引,就会进行全表扫描,因此索引的条件列也会失效。

7、in、not in可能会导致索引失效

这不属于支持的范围查询条件,不会使用索引。这里需要说明的是使用in以及not in走不走索引,实际和Mysql的版本以及表中的数据量有关系,在8.0之后的版本是走索引的。

8、索引不会包含有null值的列

只要列中包含有null值都将不会被包含在索引中,复合索引中只要有一列含有null值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时建议不要让字段的默认值为null。

9、使用短索引

对串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个char(255)的列,如果在前10个或20个字符内,多数值是惟一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。