为什么Mysql 数据库表中有索引还是查询慢

 更新时间:2022年05月11日 17:25:18   作者:​ 编程学习网   ​  
这篇文章主要介绍了为什么Mysql数据库表中有索引还是查询慢,以 user_info 这张表来作为分析的基础,在 user_info 这张表上,我们分别创建了idx_name以及idx_phone 二级索引以及 idx_age_address 联合索引展开详细内容,需要的小伙伴可以参考一下

前言:

问题分析:

在进行数据库查询的时候,我们都知道索引可以加快数据查询的效率。但是在实际的业务场景下,经常会遇到即使在表中增加了索引,但是同样还是会出现数据查询慢的问题。这就需要具体分析数据查询慢的具体原因到底是什么了。

首先需要进行确认的就是 SQL 语句中对应的条件查询中字段有没有建立索引。虽然说表中已经有索引,但是不一定 SQL 语句中的查询字段有建立索引,所以第一步应该进行 SQL 中的字段索引确认。如果没有建立对应的索引可以先尝试下建立索引再进行查询。如果已经有了索引,查询的字段也是索引字段,那么就要考虑下是不是出现了索引失效的情况。下面我们再具体分析下,看看在哪些场景下会出现索引失效的情况。

索引失效场景:

在分析索引失效场景之前,我们必须要清楚索引结构的特点是什么。

我们再来看下 Mysql 数据库索引的结构特点:

本文以 user_info 这张表来作为分析的基础,在 user_info 这张表上,我们分别创建了 idx_name 以及 idx_phone 二级索引以及 idx_age_address 联合索引。

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

进行 SQL 数据查询的时候,where 条件字段类型与实际表中字段类型不匹配的时候,Mysql 会进行隐式的数据类型转换,而类型转换会使用到内置函数,导致在进行数据查询的时候并没有使用索引。我们可以使用 explain 命令查看 sql 语句。可以看的出来在 key 栏中,对应的值为 null,说明并没有使用索引进行查询。

但是如果在按照 phone_number 字段为字符串类型进行查询的时候,Mysql 没有进行隐式的类型转换,所以最终还是走了索引。

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

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

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

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

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

使用左模糊匹配以及左右模糊匹配都会导致索引失效,但是使用右模糊匹配,还是可以走索引查询的。

由于 B+树按照索引值进行排序的,实际是按照最左前缀进行比较,而使用了 %作为最左前缀,Mysql 无法判断其有序性,因此只能进行全表扫描查询。

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

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

实际上在 Mysql 中的索引检索是遵循最左匹配原则的,同时 B+索引树的叶子节点的有序性也是建立在最左匹配原则之上,而上述的 4、5 两种情况实际违反了最左匹配原则,因此 Mysql 执行器则无法使用对应的索引进行检查查询。

6、or 分割的条件

如果 or 左边的条件存在索引,而右边的条件没有索引,不走索引
因为 OR 的含义就是两个只要满足一个即可,因此只有一个条件列进行了索引是没有意义的,只要有条件列没有进行索引,就会进行全表扫描,因此索引的条件列也会失效。

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

这里需要说明的是使用 in 以及 not in 走不走索引,实际和 Mysql 的版本以及表中的数据量有关系,在 8.0 之后的版本是走索引的。

注:此处加了地址的索引。

总结

本文总结了几种索引失效的场景,希望在大家平时项目开发时遇到类似的问题可以有对应的问题排查方向。导致索引失效的场景归结起来实际就是在索引使用上面存在瑕疵最终导致了索引失效的情况,这就像我们小时候打拳皇 97 一样,遥感和按钮的组合如果姿势不对,就没办法放出我们希望的大招。总之需要一些经验的积累,同时在写完 SQL 的时候可以进行执行检查,避免在线上出现索引失效的问题。

到此这篇关于为什么Mysql 数据库表中有索引还是查询慢的文章就介绍到这了,更多相关Mysql 查询慢原理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 深入了解mysql的4种常用、重要的数据类型

    深入了解mysql的4种常用、重要的数据类型

    对于在开发大型电子商务网站时,如果碰到有限的硬件和系统环境情况下,合理的数据库表结构的设计是必不可少的
    2014-05-05
  • mysql sql常用语句大全

    mysql sql常用语句大全

    这篇文章主要介绍了mysql sql常用语句大全,主要包括操作数据库的命令,修改表的命令及对数据库的操作,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-06-06
  • 详解在Windows环境下访问linux虚拟机中MySQL数据库

    详解在Windows环境下访问linux虚拟机中MySQL数据库

    这篇文章主要介绍了如何Windows环境下访问linux虚拟机中MySQL数据库,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • MySQL在多表上创建视图方法

    MySQL在多表上创建视图方法

    本篇文章给大家分享了MySQL在多表上创建视图方法以及相关技巧,有需要的朋友参考学习下。
    2018-06-06
  • MySQL子查询的使用详解下篇

    MySQL子查询的使用详解下篇

    子查询是在查询语句里面再嵌套一个查询,这是因为我们在提取数据的时候有很多不知道的数据产生了依赖关系。本文为大家总结了一下MySQL数据库子查询语法规则,感兴趣的可以了解一下
    2022-08-08
  • 基于unique与primary约束的区别分析

    基于unique与primary约束的区别分析

    本篇文章介绍了unique与primary约束的区别分析。需要的朋友参考下
    2013-04-04
  • Mysql sql慢查询监控脚本代码实例

    Mysql sql慢查询监控脚本代码实例

    这篇文章主要介绍了Mysql sql慢查询监控脚本代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-11-11
  • mysql5.7.22 下载过程图解

    mysql5.7.22 下载过程图解

    这篇文章主要介绍了mysql5.7.22 下载过程图解,非常不错,具有参考价借鉴价值,需要的朋友可以参考下
    2018-05-05
  • MySQL系列之六 用户与授权

    MySQL系列之六 用户与授权

    做为Mysql数据库管理员管理用户账户,是一件很重要的事,指出哪个用户可以连接服务器,从哪里连接,连接后能做什么,这篇文章主要介绍了MySQL用户与授权的相关资料,需要的朋友可以参考下
    2021-07-07
  • 在MySQL中操作克隆表的教程

    在MySQL中操作克隆表的教程

    这篇文章主要介绍了在MySQL中操作克隆表的教程,是Python入门学习中的基础知识,需要的朋友可以参考下
    2015-05-05

最新评论