Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MySQL索引失效情况

MySQL索引失效的几种情况图文详解

作者:JavaLearn-

索引并不是时时都会生效的,在一起情况下将导致索引失效,这篇文章主要给大家介绍了关于MySQL索引失效的几种情况,文章通过图文介绍的非常详细,需要的朋友可以参考下

MySQL索引是提高查询效率的重要手段。索引失效会导致查询效率下降,甚至全表扫描,影响数据库性能。以下是可能导致MySQL索引失效的情况:

1. 使用or操作符

当where语句中使用or操作符并且or两边的条件涉及到至少两个字段时,MySQL无法使用索引,会转向全表扫描。因此,应尽量避免使用or操作符。

原因:因为MySQL中的索引是根据某个字段进行排序建立的。当使用or操作符,说明有两个条件其中某个条件成立即可,而我们使用某个索引时只能判断出对应字段的条件是否成立,即使不成立,另一个条件成立时该记录也符合我们要查询的结果。所以使用索引无法做出判断。

例:

-- id为主键索引
EXPLAIN SELECT * FROM test WHERE id > 1 OR `name` = 'zs';

可以看出type为ALL:全表扫描

EXPLAIN SELECT * FROM test WHERE id > 3 OR id < 1;

可以看出type为PRIMARY:使用了主键索引;

2. 复合索引失效

如果使用了复合索引,但查询时未使用索引的第一列,索引也会失效。

原因:比如我们根据字段(t1,t2,t3)建立了复合索引,则排序规则是先按t1字段进行排序,t1字段相同再按t2字段排序,当t1、t2字段都相同时再按t3字段进行排序。如果我们的查询条件中没有使用到第一列,那么该索引也就没有办法使用。

例:

-- t1、t2列建立了符合索引
EXPLAIN SELECT * FROM test WHERE t1 = '1' AND t2 = '2';

可以看出type为ref:使用了二级索引;(当使用二级索引列于常数进行等值比较时,访问方法为ref)

-- 未使用索引的第一列t1
EXPLAIN SELECT * FROM test WHERE t2 = '1';

可以看出type为ALL:全表扫描

3. like查询

如果使用了like且以%开头,则索引会失效。

原因:模糊查询一般用在字符串的字段上,而字符串的排序规则为按字母字典序排序,如果以%开头,表示前面的字符取啥都行,则无法使用索引。

例:

EXPLAIN SELECT * FROM test WHERE t1 LIKE '1%';

可以看出type为range:使用二级索引进行范围查询。

EXPLAIN SELECT * FROM test WHERE t1 LIKE '%1';

可以看出type为ALL:全表扫描

4. 索引列上使用函数

原因:因为索引保存的是索引字段的原始值,而不是经过函数计算后的值,自然就没办法走索引了。

explain select * from test where length(t1) = 2;

5. 隐式类型转换

隐式类型转换规则:

  1. 如果一个或两个参数都是NULL,比较的结果是NULL,除了安全的<=>相等比较运算符。对于NULL <=> NULL,结果为true。不需要转换。
  2. 如果比较操作中的两个参数都是字符串,则将它们作为字符串进行比较。
  3. 如果两个参数都是整数,则将它们作为整数进行比较。
  4. 十六进制值如果不与数字进行比较,则被视为二进制字符串。
  5. 如果其中一个参数是十进制值,则比较取决于另一个参数。 如果另一个参数是十进制或整数值,则将参数与十进制值进行比较,如果另一个参数是浮点值,则将参数作为浮点值进行比较(但没有将整数类型转换为浮点类型)。
  6. 如果其中一个参数是TIMESTAMP或DATETIME列,另一个参数是常量,则在执行比较之前将常量转换为时间戳。
  7. 在所有其他情况下,参数都是作为浮点数(双精度)比较的。

隐式类型转换会导致索引失效,比如当字段类型为字符串且建有索引,而查询条件类型为数值时,会将字符串类型隐式转换为浮点型,此时索引会失效。

原因:字符串类型转换为浮点数会使用cast函数,此时索引列上使用函数,导致索引失效。

EXPLAIN SELECT * FROM test WHERE t1 = 1.1;

6. 对索引进行表达式计算

原因:因为索引保存的是索引字段的原始值,而不是 id + 1 表达式计算后的值,所以无法走索引,只能通过把索引字段的取值取出来,然后进行表达式的计算来进行条件判断,因此采用的就是全表扫描的方式。

-- num字段有二级索引
EXPLAIN SELECT * FROM test WHERE num = 1 + 10;

EXPLAIN SELECT * FROM test WHERE num + 1 = 10;

补充知识:索引设计建议

优先使用唯一索引,能够快速定位

为常用查询字段建索引

为排序、分组和联合查询字段建索引

一张表的索引数量不超过5个

表数据量少,可以不用建索引

尽量使用占用空间小的字段建索引

用idx_或unx_等前缀命名索引,方面查找

删除没用的索引,因为它会占一定空间

总结 

到此这篇关于MySQL索引失效的几种情况的文章就介绍到这了,更多相关MySQL索引失效情况内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文