当前位置: 首页 > news >正文

MySQL 索引失效的常见场景与原因分析

很多同学在建表时都会习惯性地给字段加上索引,但执行查询时发现 MySQL 并没有使用索引,依旧是 全表扫描。这是为什么呢?索引并不是万能的,有很多场景会导致 索引失效。今天我们来系统梳理一下这些坑点,帮助你在写 SQL 时少踩坑。


一、对索引字段使用函数或运算

当在 WHERE 条件中对索引字段进行函数处理或运算 时,索引通常会失效。

示例:

-- 索引字段是 create_time
SELECT * FROM user WHERE YEAR(create_time) = 2025;

由于 YEAR() 对字段做了函数计算,MySQL 无法利用原有索引,只能进行全表扫描。

正确写法

SELECT * FROM user 
WHERE create_time >= '2025-01-01' AND create_time < '2026-01-01';

👉 避免在索引字段上做运算,把计算移到常量一侧。


二、模糊查询导致索引失效

LIKE 查询中:

  • 前缀匹配能用索引(LIKE 'abc%'
  • 前置通配符会失效(LIKE '%abc'

示例:

SELECT * FROM user WHERE name LIKE '%Tom'; -- 索引失效
SELECT * FROM user WHERE name LIKE 'Tom%'; -- 可以用索引

优化思路

  • 如果必须做前置模糊,可以考虑 全文索引 或者 ES(Elasticsearch)

三、索引列出现隐式类型转换

索引字段与查询条件类型不一致 时,MySQL 会进行隐式转换,从而导致索引失效。

示例:

-- 假设 user_id 是字符串类型(varchar)
SELECT * FROM user WHERE user_id = 123; -- 索引失效

由于 123 是整型,MySQL 会将 user_id 转换为整型比较,索引失效。

正确写法

SELECT * FROM user WHERE user_id = '123';

四、组合索引未遵循最左前缀原则

组合索引 (a, b, c),查询时必须按照最左前缀顺序使用。

示例:

CREATE INDEX idx_abc ON user(a, b, c);-- 能用索引
SELECT * FROM user WHERE a = 1;
SELECT * FROM user WHERE a = 1 AND b = 2;-- 不能用索引
SELECT * FROM user WHERE b = 2;
SELECT * FROM user WHERE c = 3;

👉 记住:索引列的使用顺序非常重要


五、OR 条件可能导致索引失效

OR 条件中的某个字段未建立索引时,MySQL 往往会放弃整个索引,而进行全表扫描。

示例:

SELECT * FROM user WHERE name = 'Tom' OR age = 20;

name 有索引但 age 没有,则索引可能完全失效。

解决方案

  • 给多个字段都加上索引;
  • 或者拆分 SQL,用 UNION 合并。

六、范围查询阻断后续索引

组合索引中如果出现范围查询(>, <, BETWEEN),后续字段的索引可能无法使用。

示例:

-- 组合索引 (a, b, c)
SELECT * FROM user WHERE a = 1 AND b > 5 AND c = 10;

这里 a 可以用索引,b 也可以,但 c 可能无法利用索引。

👉 避免在组合索引中间使用范围条件。


七、NOT、!=、<> 等条件

对于 !=<>NOT IN 等否定条件,索引一般不会生效。

示例:

SELECT * FROM user WHERE age != 20;

因为 MySQL 无法直接通过索引快速排除,只能扫描更多数据。

优化思路:改写为范围查询:

SELECT * FROM user WHERE age < 20 OR age > 20;

八、IS NULL 与 IS NOT NULL

  • IS NULL 一般可以使用索引。
  • IS NOT NULL 通常会导致索引失效,因为需要扫描大部分数据。

示例:

SELECT * FROM user WHERE age IS NULL;     -- 可能用索引
SELECT * FROM user WHERE age IS NOT NULL; -- 索引可能失效

九、字段区分度太低

索引的效果与字段的 基数(区分度) 有关。
例如:性别字段只有 男/女 两种值,索引意义不大,MySQL 可能直接放弃索引。

判断区分度

SELECT COUNT(DISTINCT col) / COUNT(*) FROM table;

区分度过低的字段,不适合建立索引。


十、强制使用索引失败

有些情况下即便你使用 FORCE INDEX,MySQL 也可能不使用索引,因为优化器认为 全表扫描更快
这往往出现在小表或索引选择性不佳的场景。


总结

MySQL 索引失效的常见原因可以总结为以下几类:

  1. 写法问题:函数/运算、模糊查询、隐式转换。
  2. 索引设计问题:组合索引未遵守最左前缀、范围查询阻断后续索引。
  3. 查询逻辑问题:OR、!=、NOT IN、IS NOT NULL。
  4. 数据特点问题:字段区分度太低、小表全表扫描更快。

👉 建议开发中多用 EXPLAIN 查看执行计划,结合实际数据分布判断索引是否合理使用。

http://www.dtcms.com/a/434488.html

相关文章:

  • 四川省建设厅网站川北医学院网页制作员工作厂家
  • 从直线到环形:解锁栈、队列背后的空间与效率平衡术
  • 操作系统全解析:Windows、macOS与Linux的深度对比与选择指南(AI)
  • 网站建设推广ppt模板网站模版防被偷
  • [创业之路-647]:互联网行业的产业链
  • 甘肃省省经合局网站建设的通知知乎app开发公司
  • 计算机视觉与深度学习 | MASt3R 前馈视觉模型:原理、公式与代码实现全解析
  • 作品展示网站源码贵阳企业网站设计制作
  • 【Linux 系统】命令行参数和环境变量
  • 如何用wordpress建一个网站太原建站模板搭建
  • DNS优选 2.6.3 |解锁专业版,优选最快DNS,享受快速且私密的互联网浏览体验
  • 云浮源峰网站建设工作室地址百度免费咨询
  • wordpress 公司网站有赞分销模式佣金
  • 冀icp 网站建设做seo哪些网站会好点
  • 基于YOLOv8-OBB的SAR图像目标检测系统
  • 《强化学习数学原理》学习笔记4——贝尔曼最优方程推理过程
  • 如何缩小物联网设备的 Docker 镜像
  • 513.找树左下角的值(二叉树算法题)
  • LeetCode:84.完全平方数
  • 《API网关性能优化指南:从请求拥堵到毫秒级响应,并发下的架构重构实践》
  • 免费p2p网站建设企业管理系统开发平台
  • 报告派研读:2025年电力设备及新能源行业深度报告
  • 站长之家源码垂直电商平台有哪些?
  • K8s中的ETCD存储机制
  • 【精品资料鉴赏】397页WORD详解智慧城市顶层设计方案
  • 16种粮食谷物分类数据集5300张17类别
  • 2025基于springboot的网上蛋糕销售系统
  • SSE是什么?SSE解决什么问题?在什么场景使用SSE?
  • 算法偏见的解药:将敏捷“灵魂”注入AI伦理
  • 基于前端+Node.js 的 Markdown 笔记 PDF 导出系统完整实战