MySQL导致索引失效的原因及分析

 更新时间:2024年12月25日 09:38:35   作者:高锰酸钾_  
索引失效的原因主要包括违反最左前缀法则、范围查询、索引列上进行运算操作、字符串不加单引号以及以%开头的like模糊查询,了解这些原因有助于我们更好地使用索引,提高查询效率

MySQL什么情况下会导致索引失效

索引(Index)是数据库中一种用于快速查找和访问表中数据的结构,它类似于书的目录,通过索引可以快速定位到目标数据,而无需遍历整个表,索引的存在可以显著提高查询速度,尤其是在处理大量数据时

有时我们为了避免出现回表查询,我们就会以多个字段来创建索引,即覆盖索引,具体可看:聚簇索引、非聚簇索引、覆盖索引

使用覆盖索引最容易遇到的问题就是索引失效问题,那么哪些情况下会出现索引失效,又该如何避免索引失效呢?

索引命中

以一个tb_users表为例子:

我们以其中三个字段建立索引:

CREATE INDEX tb_user_index ON tb_users(name, status,username)

可以利用show语句可以查看我们刚刚为tb_users建立的索引:

SHOW INDEX FROM tb_users

索引字段也是有顺序的,顺序就是我们创建索引时的顺序,使用explain可以查看SQL语句的执行计划:

1.单个条件

EXPLAIN SELECT * FROM tb_users WHERE name = '崔秀英'

命中索引的长度是43,此时我们的查询条件只有name,因此命中的索引也只有name

此时查询条件中添加一个status字段:

2.两个字段

EXPLAIN SELECT * FROM tb_users WHERE name = '崔秀英' AND status = 1

此时命中索引的长度为48,表示命中了name和status

再次添加一个字段:

3.三个字段条件

EXPLAIN SELECT * FROM tb_users WHERE name = '崔秀英' AND status = 1 AND username = 'Joe Edwards'

此时三个索引字段全部命中,索引长度为131

因此命中索引的数量不一样,key_len也不一样,可以利用它来判断索引是否失效

索引失效

1.违反最左前缀法则会导致索引失效

指的是查询从索引的最左前列开始,中间不跳过索引中的列,比如:

EXPLAIN SELECT * FROM tb_users WHERE name = '崔秀英' AND username = 'Joe Edwards'

这条查询语句中,我们用两个索引字段作为了查询条件,那么理论上应该命中两个索引

但是key_len的值为43,只命中了name字段,username字段索引失效了,因为中间跳过了索引中的一列status

2.范围查询某个索引,其右边索引失效

当where条件中用索引范围查询,这个索引右边的字段会失效

EXPLAIN SELECT * FROM tb_users WHERE name = '崔秀英' AND status > 1 AND username = 'Joe Edwards'

这条查询语句使用了三个索引条件,理论上key_len为131

但是实际上命中索引长度为48,username字段未命中,原因是status使用了范围查询,因此他右边的username失效了

3.在索引列上进行运算操作,会导致索引失效

EXPLAIN SELECT * FROM tb_users WHERE SUBSTRING(0,1,name) = '崔秀英'

这里对name字段进行了截取运算操作

因此name字段并未命中,导致索引失效

4.字符串不加单引号,导致索引失效

比如说status字段,上表中我们使用的是int类型,假如我们使用了varchar类型,在查询的时候就要加单引号,如:

EXPLAIN SELECT * FROM tb_users WHERE name = '崔秀英' AND status = '1'

如果没有加单引号,MySQL就会进行多余的类型转换步骤,该步骤会导致索引失效

5.以%开头的like模糊查询,会导致索引失效

如果仅仅是尾部模糊匹配,索引不会失效,如果是头部模糊匹配,索引会失效

EXPLAIN SELECT * FROM tb_users WHERE name LIKE '%秀英'

可以看到索引命中长度为null,索引失效了

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • MySql分库分表深度指南之从策略到落地

    MySql分库分表深度指南之从策略到落地

    文章介绍了MySQL分库分表的策略及实施方法,包括分片键设计、中间件选型(如ShardingSphere、Mycat),以及如何处理跨分片查询和数据迁移,通过案例和最佳实践,文章展示了如何解决高并发、大数据量下的查询和事务问题,实现数据自治和高可用,感兴趣的朋友跟随小编一起看看吧
    2026-01-01
  • Mysql之如何实现全外连接

    Mysql之如何实现全外连接

    这篇文章主要介绍了Mysql之如何实现全外连接问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • 深入浅出的学习Mysql

    深入浅出的学习Mysql

    最近看了一本小书,网易技术部的《深入浅出MySQL数据库开发、优化与管理维护》,算是回顾一下mysql基础知识。下面这篇文章主要介绍了学习Mysql的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-02-02
  • MySql连接不上问题及解决

    MySql连接不上问题及解决

    这篇文章主要介绍了MySql连接不上问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • MySQL 5.7.17压缩版安装笔记

    MySQL 5.7.17压缩版安装笔记

    这篇文章主要介绍了MySQL 5.7.17压缩版安装笔记,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-02-02
  • MySQL约束条件及设置方式

    MySQL约束条件及设置方式

    文章主要介绍了数据库中约束条件的设置,包括主键约束、自增约束、非空约束、唯一性约束、无符合约束、默认约束和外键约束,以及如何在数据库中设置这些约束条件
    2025-01-01
  • MySQL使用正则表达式去检索指定数据库字段

    MySQL使用正则表达式去检索指定数据库字段

    这篇文章主要介绍了MySQL使用正则表达式去检索指定数据库字段,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • 在Centos7环境安装MySQL超详细教程

    在Centos7环境安装MySQL超详细教程

    MySQL是一种开源的关系型数据库管理系统(RDBMS),它是目前最流行和广泛使用的数据库之一,这篇文章主要给大家介绍了关于在Centos7环境安装MySQL的相关资料,需要的朋友可以参考下
    2023-11-11
  • 解决mysql服务器在无操作超时主动断开连接的情况

    解决mysql服务器在无操作超时主动断开连接的情况

    这篇文章主要介绍了解决mysql服务器在无操作超时主动断开连接的情况,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • MySQL中关于datetime、date、time、str之间的转化与比较

    MySQL中关于datetime、date、time、str之间的转化与比较

    这篇文章主要介绍了MySQL中关于datetime、date、time、str之间的转化与比较,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10

最新评论