MySQL进阶之路索引失效的11种情况详析

2025-03-01 17:50

本文主要是介绍MySQL进阶之路索引失效的11种情况详析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《MySQL进阶之路索引失效的11种情况详析》:本文主要介绍MySQL查询优化中的11种常见情况,包括索引的使用和优化策略,通过这些策略,开发者可以显著提升查询性能,需要的朋友可以参考下...

前言

mysql的查询优化中,索引是一项至关重要的技术,它能够大大提升数据检索的效率。本文将讨论这11种常见情况,帮助开发者更好地理解索引的使用及优化。

图示

MySQL进阶之路索引失效的11种情况详析

1. 使用不等式操作符(!=, <, >)

  • 例子
    SELECT * FROM users WHERE age != 30; 
    
  • 原理:索引通常用于等值查询(=)或范围查询(><),不等式操作无法有效利用索引。
  • 解决方案:避免使用不等式条件,改用范围查询。
    SELECT * FROM users WHERE age NOT BETWEEN 30 AND 30;
    SELECT * FROM users WHERE`age > 30`AND`age < 30;
    

2. 使用 OR 连接多个条件

  • 例子
    SELECT * FROM users WHERE age = 30 OR gender = 'male'; 
    
  • 原理OR 会导致多个独立查询,尤其当每个条件涉及不同列时,索引不会完全失效,会快速定位有索引列部分,无索引列进行全部扫描。
  • 解决方案:使用 UNION 替代 OR、创建联合索引。
    --创建联合索引
    create index idx_users_age_gender on users(age,gender);
    SELECT * FROM users WHERE age = 30 OR gender = 'male'; 
    --使用UNION合并子查询
    SELECT * FROM users WHERE age = 30
    UNION
    SELECT * FROM users WHERE gender = 'male';
    

3. 对索引字段进行计算操作

  • 例子
    SELECT * FROM orders WHERE YEAR(order_date) = 2024; 
    
  • 原理:计算和函数操作会改变数据的表现形式,索引无法直接应用。这个查询中,使用了 YEAR(order_date) 函数来提取 order_date 字段的年份,与 2024 进行比较。
  • 解决方案:1.改为直接存储处理后的数据。2.直接改为当前字段的范围查询。
    --范围查询
    SELECT * FROM orders WHERE order_date >= '2024-01-01' AND order_date < '2025-01-01';
    --直接存储处理后的数据
    ALTER TABLE orders add column order_year INT; -- 新增字段 order_year
    UPDATE orders SET order_year = YEAR(order_date); 
    SELECT * FROM orders WHERE order_year = 2024;
    

4. 对索引字段进行类型转换

  • 例子
    SELECT * FROM users WHERE CAST(age AS CHAR) = '30'; 
    
  • 原理:类型转换会导致数据类型与索引数据类型不匹配,索引失效。
  • 解决方案:确保查询条件的数据类型与索引数据类型一致,避免使用类型转换。

5. LIKE 头部模糊查询

  • 例子
    SELECT * FROM users WHERE name LIKE '%john';   
    
  • 原理LIKE 查询以 % 开头时,索引无法使用,因为数据库无法提前确定匹配的范围。
  • 解决方案:避免在 LIKE 查询中使用前缀 %,改为 LIKE 'john%'
    SELECT * FROM users WHERE name LIKE 'john%';   
    

6. NULL 值的查询

  • 例子
    SELECT * FROM users WHERE age IS NULL; 
    
  • 原理:索引对 NULL 值的查询支持有限,可能无法高效利用。
  • 解决方案:避免频繁查询 NULL 值,或者为包含 NULL 值的字段设计专门的索引、将 NULL值替换为其他默认值。
    -- 使用IFNULL() 函数
    SELECT * FROM users WHERE IFNULL(age, -1) = -1;
    -- 使用COALESCE() 函数
    SELECT * FROM users WHEREjavascript COALESCE(age, -1) = -1;
    --使用 NOT NULL 约束,修改字段默认值为 0
    ALTER TABLE users MODIFY age NOT NULL DEFAULT 0;
    

7. DISTINCT 或 GROUP BY 操作

  • 例子
    SELECT DISTINCT age FROM users;
    SELECT age, COUNT(*) FROM users GROUP BY age;
    
  • 原理DISTINCT 和 GROUP BY 操作需要去重或聚合数据。这些操作不能直接利用索引来返回唯一结果,通常会导致数据库扫描整个表(即全表扫描),尤其是在没有合适索引的情况下。
  • 解决方案:使用合适的索引(例如 GROUP BY 列上创建索引),或者将查询分解成多个步骤。
    --创建索引
    CREATE INDEX idx_users_age ON users(age);
    SELECT age, COUNT(*) FROM users GROUP BY age;
    
    --子查询获取去重结果集再查询
    SELECT age, COUNT(*) 
    FROM users 
    WHERE age IN (
        SELECT DISTINCT age 
        FROM users 
        WHERE age IS NOT NULL
    )
    GROUP BY age;
    

8. JOIN 查询中没有适当的索引

  • 例子
    SELECT * FROM users u JOIN orders o ON u.id = o.user_id; 
    
  • 原理:如果连接条件没有索引,JOIN 查询可能会导致全表扫描。
  • 解决方案:为连接字段创建索引,确保连接操作高效执行。
    CREATE INDEX idx_user_id ON orders(user_id);
    CREATE INDEX idx_user_id_users ON users(id);
    
  • 使用合适的连接类型:在某些情况下,使用 INNER JOINLEFT JOIN 或其他连接类型可以影响查询性能,选择最合适的连接方式可以帮助优化性能。

9. 排序(ORDER BY)与索引不匹配

  • 例子
    SELECT * FROM users ORDER BY name DESC,age ASC; 
    
  • 原理:如果索引的顺序与查询的排序要求不匹配,可能无法利用索引。
  • 解决方案:确保查询的排序方式与索引的顺序一致,使用复合索引支持多种排序需求。
    -- 创建复合索引
    CREATE INDEX idx_name_age ON users(name DESC, age ASC); 
    SELECT * FROM users ORDER BY name DESC, age AS编程C;
    

10. 表连接顺序不当

  • 例子
    SELECT * FROM users u JOIN orders o ON u.id =javascript o.user_id WHERE o.order_date > '2024-01-01'; 
    
  • 原理:连接顺序不当可能导致某些表的索引无法使用,从而降低查询性能。
  • 解决方案:根据数据量和索引设计优化 JOIN 顺序。
    -- 使用子查询(筛选大表后再去连接)
    SELECT * FROM 
    (SELECT js* FROM orders WHERE order_date > '2024-01-01') o
    JOIN users u ON u.id = o.user_id;
    -- 小表驱动大表(如果users表有100条,orders有20万数据)
    -- 使用 STRAIGHT_JOIN 强制左表为驱动表
    SELECT * 
    FROM users u
    STRAIGHT_JOIN orders o ON u.id = o.user_id
    WHERE o.order_date > '2024-01-01';
    

11. 启用 NO_INDEX 或 FORCE INDEX 提示时的索引失效

  • 例子
    SELECT * FROM users FORCE INDEX (idx_name) WHERE age = 30;
    
  • 原理:强制索引或禁止索引可能导致查询优化器无法选择最优的执行计划。
  • 解决方案:避免使用 FORCE INDEX 或 NO_INDEX,让数据库自动选择最优索引。

总结

在 SQL 查询优化中,合适的索引设计和查php询结构调整是提高性能的关键。通过以下措施可以避免常见的性能瓶颈:

  • 使用适当的索引来加速 DISTINCTGROUP BYJOIN 和 ORDER BY 操作。
  • 优化连接顺序,确保合理使用索引。
  • 避免强制使用或禁用索引,允许查询优化器自动选择最优执行计划。

到此这篇关于MySQL进阶之路索引失效的11种情况的文章就介绍到这了,更多相关MySQL索引失效情况内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程China编程(www.chinasem.cn)!

这篇关于MySQL进阶之路索引失效的11种情况详析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

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时候发现安装界面和别人不同,并且无论如何都没有中文选项?这个问题也

2025版mysql8.0.41 winx64 手动安装详细教程

《2025版mysql8.0.41winx64手动安装详细教程》本文指导Windows系统下MySQL安装配置,包含解压、设置环境变量、my.ini配置、初始化密码获取、服务安装与手动启动等步骤,... 目录一、下载安装包二、配置环境变量三、安装配置四、启动 mysql 服务,修改密码一、下载安装包安装地

MySQL CTE (Common Table Expressions)示例全解析

《MySQLCTE(CommonTableExpressions)示例全解析》MySQL8.0引入CTE,支持递归查询,可创建临时命名结果集,提升复杂查询的可读性与维护性,适用于层次结构数据处... 目录基本语法CTE 主要特点非递归 CTE简单 CTE 示例多 CTE 示例递归 CTE基本递归 CTE 结

C语言进阶(预处理命令详解)

《C语言进阶(预处理命令详解)》文章讲解了宏定义规范、头文件包含方式及条件编译应用,强调带参宏需加括号避免计算错误,头文件应声明函数原型以便主函数调用,条件编译通过宏定义控制代码编译,适用于测试与模块... 目录1.宏定义1.1不带参宏1.2带参宏2.头文件的包含2.1头文件中的内容2.2工程结构3.条件编

MySQL多实例管理如何在一台主机上运行多个mysql

《MySQL多实例管理如何在一台主机上运行多个mysql》文章详解了在Linux主机上通过二进制方式安装MySQL多实例的步骤,涵盖端口配置、数据目录准备、初始化与启动流程,以及排错方法,适用于构建读... 目录一、什么是mysql多实例二、二进制方式安装MySQL1.获取二进制代码包2.安装基础依赖3.清

详解MySQL中JSON数据类型用法及与传统JSON字符串对比

《详解MySQL中JSON数据类型用法及与传统JSON字符串对比》MySQL从5.7版本开始引入了JSON数据类型,专门用于存储JSON格式的数据,本文将为大家简单介绍一下MySQL中JSON数据类型... 目录前言基本用法jsON数据类型 vs 传统JSON字符串1. 存储方式2. 查询方式对比3. 索引