沉梦听雨的编程指南 沉梦听雨的编程指南
首页
  • 基础篇
  • 集合篇
  • 并发篇
  • JVM
  • 新特性
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 基础篇
  • MySql
  • Redis
  • 达梦数据库
  • Spring
  • SpringBoot
  • Mybatis
  • Shiro
  • 设计须知
  • UML画图
  • 权限校验
  • 设计模式
  • API网关
  • RPC
  • 消息队列
  • SpringCloud
  • 分布式事务
  • 云存储
  • 搜索引擎
  • 多媒体框架
  • 虚拟机
  • 开发工具篇
  • 工具库篇
  • 开发技巧篇
  • 工具类系列
  • 随笔
  • 前端环境搭建
  • HTML与CSS
  • JS学习
  • Vue3入门
  • Vue3进阶
  • 黑马Vue3
  • 脚手架搭建
  • 瑞吉外卖
  • 黑马点评
  • vue-blog
  • 沉梦接口开放平台
  • 用户中心
  • 聚合搜索平台
  • 仿12306项目
  • 壁纸小程序项目
  • RuoYi-Vue
  • 博客搭建
  • 网站收藏箱
  • 断墨寻径摘录
  • 费曼学习法
Github (opens new window)

沉梦听雨

时间是最好的浸渍剂,而沉淀是最好的提纯器🚀
首页
  • 基础篇
  • 集合篇
  • 并发篇
  • JVM
  • 新特性
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 基础篇
  • MySql
  • Redis
  • 达梦数据库
  • Spring
  • SpringBoot
  • Mybatis
  • Shiro
  • 设计须知
  • UML画图
  • 权限校验
  • 设计模式
  • API网关
  • RPC
  • 消息队列
  • SpringCloud
  • 分布式事务
  • 云存储
  • 搜索引擎
  • 多媒体框架
  • 虚拟机
  • 开发工具篇
  • 工具库篇
  • 开发技巧篇
  • 工具类系列
  • 随笔
  • 前端环境搭建
  • HTML与CSS
  • JS学习
  • Vue3入门
  • Vue3进阶
  • 黑马Vue3
  • 脚手架搭建
  • 瑞吉外卖
  • 黑马点评
  • vue-blog
  • 沉梦接口开放平台
  • 用户中心
  • 聚合搜索平台
  • 仿12306项目
  • 壁纸小程序项目
  • RuoYi-Vue
  • 博客搭建
  • 网站收藏箱
  • 断墨寻径摘录
  • 费曼学习法
Github (opens new window)
  • 基础

  • Mysql

    • MySQL基础小结
    • 索引篇
    • 讲讲回表查询
    • 讲讲索引失效问题
      • 索引失效的常见原因
        • 1. 查询条件中的函数或表达式
        • 示例:
        • 解决方法:
        • 2. 使用不等于(`!=` 或 `<>`)
        • 示例:
        • 解决方法:
        • 3. `OR` 查询中没有对所有条件字段加索引
        • 示例:
        • 解决方法:
        • 4. 模糊查询以通配符开头
        • 示例:
        • 解决方法:
        • 5. 隐式类型转换
        • 示例:
        • 解决方法:
        • 6. 查询条件中使用 IS NULL 或 IS NOT NULL
        • 示例:
        • 解决方法:
        • 7. 使用`%`的全模糊匹配
        • 示例:
        • 解决方法:
        • 8. 多列索引未按顺序使用(最左前缀原则)
        • 示例:
        • 解决方法:
        • 9. 数据量过少
        • 原因:
        • 解决方法:
        • 10. 索引失效的其他原因
      • 避免索引失效的建议
        • 总结
    • 思维导图
    • 数据库优化
    • 临时表
    • 实战篇

    • 读高性能MySQL笔记

  • Redis

  • 达梦数据库

  • 数据库
  • Mysql
沉梦听雨
2025-01-24
目录

讲讲索引失效问题

# 讲讲索引失效问题

在数据库中,索引是优化查询性能的重要工具。然而,某些情况下,即使为字段创建了索引,查询时仍可能无法使用索引,导致性能下降。这种现象称为索引失效。


# 索引失效的常见原因

# 1. 查询条件中的函数或表达式

当查询条件中对索引字段进行了函数操作或表达式计算时,索引会失效。

# 示例:

-- 假设 `name` 字段有索引
SELECT * FROM users WHERE UPPER(name) = 'JOHN';
1
2
  • 原因:UPPER(name) 会对每一行的数据进行操作,使得索引无法直接用于查询。

# 解决方法:

避免对索引字段进行函数或表达式操作。

SELECT * FROM users WHERE name = 'john';
1

# 2. 使用不等于(!= 或 <>)

不等于操作符会导致全表扫描,因为无法通过索引快速过滤不满足条件的记录。

# 示例:

SELECT * FROM users WHERE age != 30;
1
  • 原因:索引无法对 != 操作快速定位所有可能的值。

# 解决方法:

优化查询逻辑,尽量使用范围查询或其他条件。


# 3. OR 查询中没有对所有条件字段加索引

如果 OR 连接的多个条件中,某些字段没有索引,则索引会失效。

# 示例:

SELECT * FROM users WHERE age = 25 OR name = 'John';
1
  • 如果 age 和 name 字段没有同时建立索引,则可能导致索引失效。

# 解决方法:

为所有可能的查询字段建立索引,或将 OR 查询拆分为 UNION。

SELECT * FROM users WHERE age = 25
UNION
SELECT * FROM users WHERE name = 'John';
1
2
3

# 4. 模糊查询以通配符开头

在 LIKE 语句中,如果通配符(%或_)出现在字符串开头,则索引失效。

  • % 匹配 零个或多个字符,可以匹配任意长度的字符串。

  • _ 匹配 单个字符,即它代表一个任意字符

# 示例:

SELECT * FROM users WHERE name LIKE '%john';
1
  • 原因:数据库无法确定以 “john” 结尾的记录范围,只能进行全表扫描。

# 解决方法:

避免通配符出现在开头,或使用全文索引(Full-Text Index)。

SELECT * FROM users WHERE name LIKE 'john%';
1

# 5. 隐式类型转换

如果查询条件的字段类型和传入的值类型不一致,数据库可能会进行隐式转换,导致索引失效。

# 示例:

假设 id 是一个字符串类型字段:

SELECT * FROM users WHERE id = 123;
1
  • 原因:id 字段为字符串类型,而 123 是整数,数据库会将 id 字段转换为数字,导致索引失效。

# 解决方法:

确保查询条件的值类型与字段类型一致。

SELECT * FROM users WHERE id = '123';
1

# 6. 查询条件中使用 IS NULL 或 IS NOT NULL

对索引字段进行 IS NULL 或 IS NOT NULL 查询时,索引通常会失效。

# 示例:

SELECT * FROM users WHERE age IS NOT NULL;
1
  • 原因:索引通常不存储 NULL 值。

# 解决方法:

  • 尽量避免查询 NULL 值,或使用覆盖索引等其他优化方法。

# 7. 使用%的全模糊匹配

即使没有通配符在开头,全模糊匹配也可能导致索引失效。

# 示例:

SELECT * FROM users WHERE name LIKE '%john%';
1
  • 原因:全模糊匹配需要扫描所有数据,不能直接利用索引。

# 解决方法:

使用全文索引或专门的搜索工具(如 Elasticsearch)。


# 8. 多列索引未按顺序使用(最左前缀原则)

对于复合索引,如果查询条件未按照索引字段的顺序使用,可能导致索引失效。

# 示例:

假设有一个复合索引 (name, age):

SELECT * FROM users WHERE age = 30;
1
  • 原因:复合索引的查询必须从最左侧字段name开始,否则索引无法生效。

# 解决方法:

遵循最左前缀原则,尽量使用索引的最左字段。

SELECT * FROM users WHERE name = 'John' AND age = 30;
1

# 9. 数据量过少

如果表中的数据量过少,数据库优化器可能会直接选择全表扫描,而不是使用索引。

# 原因:

  • 对小表来说,全表扫描的性能可能与索引查询相差无几,因此优化器可能会选择全表扫描。

# 解决方法:

无需特别优化,此时索引失效是数据库的优化行为。


# 10. 索引失效的其他原因

  • 统计信息过期:数据库优化器依赖统计信息,如果统计信息过时可能导致错误的执行计划。
  • 使用非主键或唯一索引字段进行排序:排序操作可能触发全表扫描。
  • 分页查询中偏移量过大:分页查询时,较大的偏移量可能导致性能问题。

# 避免索引失效的建议

  1. 设计合理的索引:
    • 为常用查询条件字段建立索引。
    • 尽量避免在索引字段上使用函数、表达式和计算。
    • 使用覆盖索引优化查询。
  2. 遵循最左前缀原则:
    • 复合索引要按顺序使用,从左到右。
  3. 避免隐式类型转换:
    • 确保查询条件与字段类型一致。
  4. 避免模糊查询的通配符开头:
    • 如果需要模糊匹配,考虑全文索引或外部搜索工具。
  5. 及时更新统计信息:
    • 对于大表,定期分析表,确保优化器选择最优的执行计划。

# 总结

索引失效的主要原因是查询条件和索引设计不匹配。通过合理设计索引、优化查询语句以及遵循索引使用规则,可以有效避免索引失效问题,提升查询性能。在实际开发中,定期分析执行计划(EXPLAIN)是发现索引失效的有效方法。

上次更新: 2025/2/6 17:50:04
讲讲回表查询
思维导图

← 讲讲回表查询 思维导图→

Theme by Vdoing | Copyright © 2023-2025 沉梦听雨 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式