详解MYSQL索引失效问题排查

目录

一、快速定位索引失效的步骤

1. 使用 EXPLAIN 分析执行计划详解Mysql的Explain语句

2. 确认索引是否存在

3. 检查查询条件是否符合索引规则

二、常见索引失效场景及解决方法 

1. 索引列参与计算或函数

2. 隐式类型转换

3. 使用 LIKE 以通配符开头

4. 使用 OR 连接非索引列 

5. 索引选择性过低

6. 联合索引顺序错误

7. 使用 != 或 <> 操作符

8. IS NULL 或 IS NOT NULL 条件

9. 多个索引ORDER BY 顺序不一致

10.  全文索引的误用

三、高级排查工具

1. 开启慢查询日志

2. 使用 OPTIMIZER_TRACE 分析优化器决策

3. 强制使用索引测试

四、总结


一、快速定位索引失效的步骤

1. 使用 EXPLAIN 分析执行计划详解Mysql的Explain语句

EXPLAIN SELECT * FROM users WHERE age = 25 AND name = 'John';

重点关注以下字段:

  • type:若显示 ALL(全表扫描)或 index(全索引扫描),可能索引未生效。

  • key:实际使用的索引名称,若为 NULL 表示未使用索引。

  • rows:预估扫描的行数,数值过大说明索引可能未生效。

  • Extra:若出现 Using filesort 或 Using temporary,可能索引未被用于排序或分组。

2. 确认索引是否存在

SHOW INDEX FROM users;  -- 查看表的索引信息

确保查询涉及的列(尤其是 WHEREJOINORDER BY 中的列)已创建索引。

3. 检查查询条件是否符合索引规则

  • 最左前缀原则:联合索引 (a, b, c) 必须按顺序使用,跳过中间列会导致后续列无法使用索引。

    WHERE a=1 AND c=3;  -- 仅使用到 a 列的索引,c 列无法生效
  • 范围查询阻断索引:范围查询(><BETWEEN)后的列无法使用索引。

    WHERE a>10 AND b=20;  -- 仅 a 列使用索引,b 列无法生效

二、常见索引失效场景及解决方法 

1. 索引列参与计算或函数

  • 失效示例

    SELECT * FROM users WHERE YEAR(create_time) = 2023;  -- 对索引列使用函数
    SELECT * FROM users WHERE age + 10 > 30;            -- 对索引列进行运算
  • 优化方法:改写为直接使用索引列。

    SELECT * FROM users WHERE create_time BETWEEN '2023-01-01' AND '2023-12-31';

2. 隐式类型转换

  • 失效示例

    -- 假设 phone 是 VARCHAR 类型,但传入数字
    SELECT * FROM users WHERE phone = 13800138000;  -- 字符串转数字导致索引失效
  • 优化方法:确保数据类型一致。

    SELECT * FROM users WHERE phone = '13800138000';

3. 使用 LIKE 以通配符开头

  • 失效示例

    SELECT * FROM users WHERE name LIKE '%John%';  -- 前导通配符导致索引失效
  • 优化方法:尽量使用右通配符。

    SELECT * FROM users WHERE name LIKE 'John%';  -- 可能使用索引

4. 使用 OR 连接非索引列 

  • 失效示例

    -- 假设 age 有索引,address 无索引
    SELECT * FROM users WHERE age = 25 OR address = 'Beijing';  -- 全表扫描
  • 优化方法:改用 UNION 拆分查询。

    SELECT * FROM users WHERE age = 25 
    UNION 
    SELECT * FROM users WHERE address = 'Beijing';

5. 索引选择性过低

  • 问题现象:索引列的值重复率过高(如性别字段),MySQL 可能放弃使用索引。

  • 优化方法:删除低选择性索引,或结合其他列创建联合索引。

    ALTER TABLE users ADD INDEX idx_gender_age (gender, age);

6. 联合索引顺序错误

  • 问题现象:联合索引 (a, b, c),但查询未按最左前缀顺序使用,导致索引部分失效。

  • 失效示例

    -- 索引 (a, b, c)
    SELECT * FROM table WHERE b = 2 AND a = 1;  -- 正常使用索引(优化器自动调整顺序)
    SELECT * FROM table WHERE a = 1 AND c = 3;  -- 仅用到 a 列索引,c 未生效
    SELECT * FROM table WHERE b = 2;            -- 索引完全失效(未使用最左列 a)
  • 优化方法

    • 调整查询条件顺序,确保按最左前缀匹配。

    • 根据高频查询场景,设计合理的联合索引顺序。

7. 使用 != 或 <> 操作符

  • 问题现象:非等值查询(如 !=NOT IN)可能导致索引失效。

  • 失效示例

    SELECT * FROM users WHERE age != 25;       -- 可能全表扫描
    SELECT * FROM orders WHERE status NOT IN (1, 2);  
  • 优化方法

    • 改写为等值查询或范围查询:

      SELECT * FROM users WHERE age < 25 OR age > 25;  -- 仍可能失效,需结合其他条件
    • 若数据分布倾斜,强制使用索引(需测试验证):

      SELECT * FROM users FORCE INDEX(idx_age) WHERE age != 25;

8. IS NULL 或 IS NOT NULL 条件

  •  问题现象:索引列上使用 IS NULL 或 IS NOT NULL 可能导致索引失效。

  • 失效示例

    SELECT * FROM users WHERE phone IS NULL;      -- 可能全表扫描
  • 优化方法:若 NULL 值较少,添加条件冗余字段:

    ALTER TABLE users ADD COLUMN is_phone_null TINYINT(1) DEFAULT 0;
    CREATE INDEX idx_phone_null ON users(is_phone_null);
    SELECT * FROM users WHERE is_phone_null = 1;

    9. 多个索引ORDER BY 顺序不一致

    •  问题现象:排序字段顺序与索引顺序不匹配,导致无法利用索引排序。

    • 失效示例

      -- 索引 (a, b)
      SELECT * FROM table WHER ORDER BY a ASC, b DESC;  -- 2个索引顺序不一致导致失效
      
    • 优化方法:调整联合索引顺序,同升同降。

      SELECT * FROM table WHER ORDER BY a ASC, b ASC;  同升同降
      

    10.  全文索引的误用

    •  问题现象:错误使用 LIKE 或 MATCH AGAINST 导致索引失效。

    • 失效示例

      -- 未使用全文索引
      SELECT * FROM articles WHERE content LIKE '%database%';  
      
    • 优化方法

      • 对文本搜索需求改用全文索引(FULLTEXT Index)。

      • 避免在全文索引列上混合使用 LIKE 和 MATCH

        SELECT * FROM articles WHERE MATCH(content) AGAINST('database');

    三、高级排查工具

    1. 开启慢查询日志

    -- 配置 my.cnf
    slow_query_log = 1
    slow_query_log_file = /var/log/mysql/slow.log
    long_query_time = 2   -- 记录执行超过2秒的SQL

    通过慢日志定位高频低效 SQL。

    2. 使用 OPTIMIZER_TRACE 分析优化器决策

    SET optimizer_trace = 'enabled=on';
    SELECT * FROM users WHERE age = 25;  -- 执行你的查询
    SELECT * FROM information_schema.optimizer_trace;  -- 查看优化器选择索引的过程

    3. 强制使用索引测试

    SELECT * FROM users FORCE INDEX (idx_age) WHERE age = 25;  -- 强制使用索引

    对比强制索引前后的执行时间,判断优化器是否选错索引。

    四、总结

    • 核心原则:索引失效的本质是 无法快速定位数据范围

    • 关键检查点

      • 避免对索引列进行计算或函数操作。

      • 确保查询条件符合最左前缀原则。

      • 注意隐式类型转换和通配符使用。

    • 工具辅助EXPLAIN、慢查询日志、OPTIMIZER_TRACE 是排查利器。

    本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
    如若转载,请注明出处:http://www.pswp.cn/news/907184.shtml
    繁体地址,请注明出处:http://hk.pswp.cn/news/907184.shtml

    如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

    相关文章

    在 springboot3.x 使用 knife4j 以及常见报错汇总

    目录 引言&#xff1a; 引入依赖&#xff1a; 配置文件&#xff1a; 过滤静态资源&#xff1a; 增强模式&#xff1a; 便捷地址访问&#xff1a; 常见问题&#xff1a; 注解使用实例&#xff1a; &#x1f4c4; ​文档参考地址​&#xff1a; SpringBoot 3.x 结合 …

    【C/C++】环形缓冲区:高效数据流转核心

    文章目录 1 核心结构与原理1.1 组成1.2 内存布局1.3 关键操作 2 实现细节与优化2.1 满/空状态的判断2.2 多线程安全&#xff08;无锁实现&#xff09;2.3 性能优化 3 典型应用场景4 代码示例5 优缺点6 对比7 进阶 环形缓冲区&#xff08;Ring Buffer&#xff09;&#xff0c;又…

    功耗仅4W!迷你服务器黑豹X2(Panther X2)卡刷、线刷刷入Armbian(ubuntu)系统教程

    功耗仅4W&#xff01;迷你服务器黑豹X2&#xff08;Panther X2&#xff09;卡刷、线刷刷入Armbian&#xff08;ubuntu&#xff09;系统教程 前言 前段时间逛海鲜市场的时候留意到一个矿渣盒子&#xff0c;黑豹x2&#xff0c;又是一个类似迅雷赚钱宝这样的挖矿项目已经gg的定制…

    【Elasticsearch】更新操作原理

    Elasticsearch 的更新操作&#xff08;如 _update 和 _update_by_query&#xff09;在底层实现上有一些复杂的原理&#xff0c;这些原理涉及到 Elasticsearch 的数据存储机制、索引机制以及事务日志&#xff08;Translog&#xff09;的使用。以下是 Elasticsearch 更新操作的主…

    【C++】红黑树的实现

    目录 前言 一、红黑树的概念 二、红黑树的实现 三、红黑树的查找 四、红黑树的验证 五、红黑树的删除 总结 前言 本文讲解红黑树&#xff0c;主要讲解插入部分的实现&#xff0c;建议在理解了AVL树的旋转后再来学习红黑树&#xff0c;因为红黑树也涉及旋转&#xff0c;并…

    IPv4地址的主要配置项介绍

    1. IPv4 主要配置项 (1) IP 地址&#xff08;IP Address&#xff09; 作用&#xff1a;唯一标识网络中的设备&#xff08;如 192.168.1.100&#xff09;。分类&#xff1a; 静态 IP&#xff1a;手动配置&#xff0c;适用于服务器、打印机等固定设备。动态 IP&#xff08;DHCP…

    nginx 基于IP和用户的访问

    nginx的下载 yum install nginx.x86_64 -y 启动服务 systemctl enable --now nginx.service 查看服务目录 [rootwebserver ~]# rpm -ql nginx /usr/bin/nginx-upgrade /usr/lib/systemd/system/nginx.service /usr/share/man/man3/nginx.3pm.gz /usr/share/man/man8/nginx…

    Debian操作系统全面解析:从起源到应用

    Debian 操作系统全面解析:从起源到应用 在开源操作系统的广袤天地中,Debian 占据着极为重要的地位。它凭借自身诸多突出特性,吸引了全球无数用户与开发者的目光,从个人桌面应用到大型服务器部署,从普通办公场景到专业科研领域,Debian 都展现出了强大的适应性与可靠性,为…

    【springMVC】springMVC学习系列一:springMVC的组件

    系列文章目录 前言 spring mvc 它解决了什么问题呢&#xff1f; 1.URL映射 2. 表单参数映射 3. 调用目标Control 4. 数据模型映射 5. 视图解析 6. 异常处理 上述解决在spring mvc 中都体现在如下组件当中 HandlerMapping&#xff1a; url与控制器的映谢 HandlerAdapter&#…

    【Vue Vapor Mode :技术突破与性能优化的可能性】

    Vue Vapor Mode &#xff1a;技术突破与性能优化的可能性 前言 作为一名有着Vue 2经验和Vue 3经验的开发者&#xff0c;你一定深刻体会过Vue从Options API到Composition API的演进&#xff0c;也感受过Vue 3在性能上相比Vue 2的显著提升。现在&#xff0c;Vue团队正在开发一个…

    MySQL数据库零基础入门教程:从安装配置到数据查询全掌握【MySQL系列】

    第1章&#xff1a;认识MySQL 1.1 什么是MySQL&#xff1f; MySQL是一种开源的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;由瑞典MySQL AB公司开发&#xff0c;现由Oracle公司维护。它使用结构化查询语言&#xff08;SQL&#xff09;进行数据库的管理和操…

    AXI3、AXI4 和 AXI5 的详细差异对比

    AXI3、AXI4 和 AXI5 的详细差异对比 摘要&#xff1a;AXI (Advanced eXtensible Interface) 是 ARM 公司提出的高性能片上总线协议&#xff0c;广泛用于 SoC (System on Chip) 设计中&#xff0c;以实现高效的数据传输和系统互连。AXI 协议随着版本的迭代不断演进&#xff0c;从…

    向量数据库该如何选择?Milvus 、ES、OpenSearch 快速对比:向量搜索能力与智能检索引擎的应用前景

    ​ 1.milvus VS ES Milvus 的亮点 功能性&#xff1a;Milvus 不仅支持基本的向量相似性搜索&#xff0c;还支持稀疏向量、批量向量、过滤搜索和混合搜索功能等高级功能。 灵活性&#xff1a;Milvus 支持多种部署模式和多个 SDK&#xff0c;所有这些都在一个强大的集成生态系…

    SQL进阶之旅 Day 4:子查询与临时表优化

    文章标题 【SQL进阶之旅 Day 4】子查询与临时表优化 文章内容 开篇&#xff1a;SQL进阶之旅的第4天 在“SQL进阶之旅”系列中&#xff0c;第4天的主题是子查询与临时表优化。这是SQL开发中不可或缺的一部分&#xff0c;尤其在处理复杂查询时&#xff0c;合理使用子查询和临…

    Python学习(2) ----- Python的类型

    在 Python 中&#xff0c;一切皆对象&#xff0c;每个对象都有类型。下面是 Python 中的常见内置类型分类和示例&#xff1a; &#x1f7e1; 1. 数字类型&#xff08;Numeric Types&#xff09; 类型说明示例int整数5, -42float浮点数3.14, -0.5complex复数1 2j a 10 …

    跨协议协同智造新实践:DeviceNet-EtherCAT网关驱动汽车焊接装配效能跃迁

    在汽车制造领域&#xff0c;机器人协作对于提升生产效率与产品质量至关重要。焊接、装配等关键环节&#xff0c;需要机器人与各类设备紧密配合。JH-DVN-ECT疆鸿智能的devicenet从站转ethercat主站协议网关&#xff0c;成为实现这一高效协作的得力助手&#xff0c;尤其是在连接欧…

    nginx之proxy_buffering的作用

    Nginx 的缓冲机制是为了让后端能更快释放资源&#xff0c;而不是卡在慢客户端上&#xff0c;从而提升整体性能和并发能力。 现实中客户端和后端服务器之间的传输速率可能差异很大。Nginx 的缓冲机制正是为了解决这个不匹配问题。 假设没有缓冲&#xff08;即 proxy_buffering…

    数据库相关问题

    1.保留字 1.1错误案例&#xff08;2025/5/27&#xff09; 报错&#xff1a; java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near condition, sell…

    GO 语言进阶之 进程 OS与 编码,数据格式转换

    更多个人笔记见&#xff1a; github个人笔记仓库 gitee 个人笔记仓库 个人学习&#xff0c;学习过程中还会不断补充&#xff5e; &#xff08;后续会更新在github上&#xff09; 文章目录 进程信息OS操作基本例子 编码相关HASH 哈希Base64 encoding 基础64编码 数据格式转换和处…

    如何用Spring Cache实现对Redis的抽象

    我们在进行Java项目开发时候&#xff0c;经常会用到Redis缓存例如数据库里的一些信息、手机验证码之类的&#xff0c;正常写法就会像去连mysql一样&#xff0c;这种硬编码的方式肯定是非常不合适的。 Autowireprivate UserMapper userMapper;Autowireprivate StringCommand str…