MySQL中什么情况下会出现索引失效?如何排查索引失效?

2024-04-26 07:20

本文主要是介绍MySQL中什么情况下会出现索引失效?如何排查索引失效?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 1-引言:什么是MySQL的索引失效?(What、Why)
    • 1-1 索引失效定义
    • 1-2 为什么排查索引失效
  • 2- 索引失效的原因及排查(How)
    • 2-1 索引失效的情况
      • ① 索引列参与计算
      • ② 对索引列进行函数操作
      • ③ 查询中使用了 OR 两边有范围查询 > 或 <
      • ④ like 操作:以 % 开头的 like 查询
      • ⑤ 不等于比较 !=
      • ⑥ order by
      • ⑦ 使用 IN
    • 2-2 索引失效的排查
      • 使用 explain 排查
      • 需要关注的字段:type、key、extra
  • 3- 总结:索引失效知识点小结


image.png

1-引言:什么是MySQL的索引失效?(What、Why)

1-1 索引失效定义

  • 在MySQL中,索引是用来加快检索数据库记录的一种数据结构
  • 索引失效指的是在进行查询操作时,本应该使用索引来提升查询效率的场景下,数据库没有利用索引,而是采用了全表扫描的方式,这会大大增加查询时间和系统负担。

1-2 为什么排查索引失效

排查索引失效的原因是至关重要的,主要有以下方面:

  • 1. 提高查询效率:索引的主要目的是加快数据检索速度。当索引失效时,数据库系统可能退回到更慢的查询方法,如全表扫描,这会显著增加查询时间和降低整体性能。
  • 2. 降低服务器负载:使用索引可以显著减少数据库处理查询所需处理的数据量,从而减少CPU使用率和IO读写。如果索引失效,数据库必须加载更多数据,这会增加服务器的负载和资源消耗。

2- 索引失效的原因及排查(How)

2-1 索引失效的情况

  • 以以下的学生信息表举例
CREATE TABLE `student_info` (`student_id` int(11) NOT NULL AUTO_INCREMENT,`student_name` varchar(50) NOT NULL,`student_age` int(11) DEFAULT NULL,`enrollment_date` datetime DEFAULT NULL,PRIMARY KEY (`student_id`),UNIQUE KEY `student_name` (`student_name`),KEY `student_age` (`student_age`),KEY `enrollment_date` (`enrollment_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  • 表的索引情况:
  • 总结来说,表 student_info 有四个字段上定义了索引:
    • 一个主键索引 student_id
    • 一个唯一索引 student_name
    • 以及两个普通索引 student_ageenrollment_date

image.png

① 索引列参与计算

  • 正常的通过 age 去做查询
    • 走的是 student_age 的索引
explain select * from student_info where student_age=21;

image.png

  • 如果索引列参与了计算进行查询
    • 索引失效
explain select * from student_info where student_age+1 =21;

image.png

  • 如果不是对列进行计算,而是对列等号右侧的值进行计算,结果还是走索引的。

image.png


② 对索引列进行函数操作

  • 正常的查询——>走索引
explain select * from student_info where enrollment_date = '2022-09-04 08:00:00';

image.png

  • 如果对查询的字段加上函数操作时,索引失效
explain select * from student_info where YEAR(enrollment_date) = 2022;

image.png


③ 查询中使用了 OR 两边有范围查询 > 或 <

  • 正常情况查询,查询使用 student_name 索引
explain select * from student_info where student_name='Helen' and student_age>15;

image.png

  • 如果使用了 OR 进行查询,两边包含范围查询 > 或 <
    • 此时索引失效
explain select * from student_info where student_name='Helen' or student_age>15;

image.png

  • 如果没有范围查询下使用 OR 还是正常走索引
explain select * from student_info where student_name='Helen' or student_age=18;

image.png


④ like 操作:以 % 开头的 like 查询

  • 以 % 开头的 LIKE 查询比如 LIKE ‘%abc’;;

⑤ 不等于比较 !=

  • 在MySQL中 != 比较有可能会导致不走索引,但如果对 id 进行 != 比较,是有可能走索引的。
  • != 比较是否走索引,与索引的选择、数据分布情况有关,不单是由于查询包含 != 而引起的。

⑥ order by

  • 如果使用 order by 时,表中的数据量很小,数据库会直接在内存中进行排序,而不使用索引

image.png


⑦ 使用 IN

  • 使用 IN 的时候,有可能走索引,也有可能不走索引。当在 IN 的取值范围比较大的时候有可能会导致索引失效,走全表扫描(NOT ININ的失效场景相同)。

2-2 索引失效的排查

使用 explain 排查

  • 和 MySQL 慢查询的排查类似,使用 Explain 语句来进行排查。

需要关注的字段:type、key、extra

  • 我们可以根据 key、type、extra 来判断一条语句是否走了索引。
  • 一般走索引的情况 :
    • key 值不为 null
    • type 值应该为 ref、eq_ref、range、const 这几个
    • extra 的话如果是 NULL,或者 using indedx,using index condition 都是可以的

索引失效情况

  • 如果一条语句出现了 type 值为 all、key 为 nullextra = Using where 此时是索引失效了

此时就需要排查索引失效的原因

    1. 索引是否符合最左前缀匹配
    1. 查询语句出现以上 7 种情况

3- 总结:索引失效知识点小结

MySQL中什么情况下会出现索引失效?如何排查索引失效?
回答
:::info
MySQL中索引失效的情况有

    1. 比如联合索引在查询的过程中不符合最左前缀原则,此时联合索引会失效
    1. 查询的语句 索引列 进行计算,此时会使得索引失效
    1. 查询的语句 对索引列进行了函数操作,比如利用了 **YEAR()** 函数
    1. 查询语句中 包含 **OR** ,且 OR 两侧有范围查询 也就是 **>****<** 此时索引会失效
    1. 查询语句中 使用了 **like****like** 中存在 以**%** 开头的匹配,此时索引会失效
    1. 查询语句中 使用了 **!=** 进行比较,但这种情况也和数据的分布情况有关系,
    1. 当数据表中的数据较少,使用 **order by** 的时候,可能会不走索引直接在内存中进行排序
    1. 当使用 **IN**** **时候取值范围比较大的时候有可能会导致索引失效

索引失效的排查

  • ① 使用 Explain 对 SQL 语句进行排查
  • 需要 关注的字段有 **type****key****extra**
  • 如果一条语句出现了 type 值为 all、key 为 nullextra = Using where 此时是索引失效了

此时就需要排查索引失效的原因,是否存在以上情况
:::

这篇关于MySQL中什么情况下会出现索引失效?如何排查索引失效?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/936940

相关文章

Oracle查询表结构建表语句索引等方式

《Oracle查询表结构建表语句索引等方式》使用USER_TAB_COLUMNS查询表结构可避免系统隐藏字段(如LISTUSER的CLOB与VARCHAR2同名字段),这些字段可能为dbms_lob.... 目录oracle查询表结构建表语句索引1.用“USER_TAB_COLUMNS”查询表结构2.用“a

MySQL中EXISTS与IN用法使用与对比分析

《MySQL中EXISTS与IN用法使用与对比分析》在MySQL中,EXISTS和IN都用于子查询中根据另一个查询的结果来过滤主查询的记录,本文将基于工作原理、效率和应用场景进行全面对比... 目录一、基本用法详解1. IN 运算符2. EXISTS 运算符二、EXISTS 与 IN 的选择策略三、性能对比

MySQL常用字符串函数示例和场景介绍

《MySQL常用字符串函数示例和场景介绍》MySQL提供了丰富的字符串函数帮助我们高效地对字符串进行处理、转换和分析,本文我将全面且深入地介绍MySQL常用的字符串函数,并结合具体示例和场景,帮你熟练... 目录一、字符串函数概述1.1 字符串函数的作用1.2 字符串函数分类二、字符串长度与统计函数2.1

SQL Server跟踪自动统计信息更新实战指南

《SQLServer跟踪自动统计信息更新实战指南》本文详解SQLServer自动统计信息更新的跟踪方法,推荐使用扩展事件实时捕获更新操作及详细信息,同时结合系统视图快速检查统计信息状态,重点强调修... 目录SQL Server 如何跟踪自动统计信息更新:深入解析与实战指南 核心跟踪方法1️⃣ 利用系统目录

MySQL 内存使用率常用分析语句

《MySQL内存使用率常用分析语句》用户整理了MySQL内存占用过高的分析方法,涵盖操作系统层确认及数据库层bufferpool、内存模块差值、线程状态、performance_schema性能数据... 目录一、 OS层二、 DB层1. 全局情况2. 内存占js用详情最近连续遇到mysql内存占用过高导致

Mysql中设计数据表的过程解析

《Mysql中设计数据表的过程解析》数据库约束通过NOTNULL、UNIQUE、DEFAULT、主键和外键等规则保障数据完整性,自动校验数据,减少人工错误,提升数据一致性和业务逻辑严谨性,本文介绍My... 目录1.引言2.NOT NULL——制定某列不可以存储NULL值2.UNIQUE——保证某一列的每一

解密SQL查询语句执行的过程

《解密SQL查询语句执行的过程》文章讲解了SQL语句的执行流程,涵盖解析、优化、执行三个核心阶段,并介绍执行计划查看方法EXPLAIN,同时提出性能优化技巧如合理使用索引、避免SELECT*、JOIN... 目录1. SQL语句的基本结构2. SQL语句的执行过程3. SQL语句的执行计划4. 常见的性能优

SQL Server 中的 WITH (NOLOCK) 示例详解

《SQLServer中的WITH(NOLOCK)示例详解》SQLServer中的WITH(NOLOCK)是一种表提示,等同于READUNCOMMITTED隔离级别,允许查询在不获取共享锁的情... 目录SQL Server 中的 WITH (NOLOCK) 详解一、WITH (NOLOCK) 的本质二、工作

MySQL 强制使用特定索引的操作

《MySQL强制使用特定索引的操作》MySQL可通过FORCEINDEX、USEINDEX等语法强制查询使用特定索引,但优化器可能不采纳,需结合EXPLAIN分析执行计划,避免性能下降,注意版本差异... 目录1. 使用FORCE INDEX语法2. 使用USE INDEX语法3. 使用IGNORE IND

SQL Server安装时候没有中文选项的解决方法

《SQLServer安装时候没有中文选项的解决方法》用户安装SQLServer时界面全英文,无中文选项,通过修改安装设置中的国家或地区为中文中国,重启安装程序后界面恢复中文,解决了问题,对SQLSe... 你是不是在安装SQL Server时候发现安装界面和别人不同,并且无论如何都没有中文选项?这个问题也