mysql执行SQL时如何判断是否走索引_mysql执行流程分析

3次阅读

EXPLAIN 是查看 MySQL 索引使用情况最直接的方法,需关注 key(非 NULL 表示用索引)、type(const/ref/range 为走索引,ALL 为全表扫描)、rows(远小于总行数说明过滤有效)、Extra(出现 Using filesort 或 temporary 表示额外开销)。

mysql 执行 SQL 时如何判断是否走索引_mysql 执行流程分析

EXPLAIN 看执行计划是最直接的方法

MySQL 不会主动告诉你“用了哪个索引”,但 EXPLAIN 会把优化器的决策摊开给你看。在 SQL 前加 EXPLAIN,重点关注 typekeyrowsExtra 这几列:

  • key 列非 NULL(比如显示 idx_user_id)→ 实际使用了该索引
  • typeconst / ref / range → 通常走索引;如果是 ALL → 全表扫描,没走索引
  • rows 值远小于表总行数 → 说明索引过滤有效;接近总数则可能失效
  • Extra 出现 Using filesortUsing temporary → 即使走了索引,排序 / 分组仍可能回表或额外开销

注意:仅 key 非空不等于“高效”,还要结合 typerows 综合判断。

哪些写法会让索引“悄悄失效”

索引存在 ≠ 被使用。常见隐形失效场景包括:

  • 对索引字段做函数操作:WHERE YEAR(create_time) = 2023create_time 上的索引失效
  • 隐式类型转换WHERE user_id = '123'user_idINT)→ 可能放弃索引
  • 使用 !=NOT IN(尤其右侧含 NULL)→ 优化器常弃用索引
  • LIKE 以通配符开头:LIKE '%abc' → 无法利用 B+ 树前缀匹配特性
  • 联合索引未按最左前缀使用:INDEX (a, b, c),只查 WHERE b = 1 → 不走索引

这些不是语法错误,SQL 能正常执行,但执行计划里 key 会是 NULLtype 变成 ALL

FORCE INDEX 能强制走索引,但要小心

当优化器误判(比如统计信息过期、小表误选全表扫描),可用 FORCE INDEX 干预:

SELECT * FROM orders FORCE INDEX (idx_status_created) WHERE status = 'paid' AND created_at > '2024-01-01';

但它不解决根本问题:

  • 如果索引本身设计不合理(比如缺失覆盖字段),强制后反而更慢
  • 后续数据分布变化后,FORCE INDEX 可能从“救急”变“拖累”
  • MySQL 8.0+ 中,USE INDEX 更温和,IGNORE INDEX 有时比硬刚更有用

上线前务必用真实数据量 + EXPLAIN FORMAT=JSON 验证效果,别只看 开发环境

执行流程中索引在哪一步介入

简化版 MySQL 执行流程:连接 → 解析 → 优化(生成执行计划)→ 执行 → 返回。索引参与的是「优化」和「执行」两步:

  • 优化阶段:优化器基于统计信息(SHOW INDEX FROM tbl + INFORMATION_SCHEMA.STATISTICS)、成本模型,决定是否用索引、用哪个、是否下推条件(ICP)
  • 执行阶段:存储引擎(如 InnoDB)按执行计划调用索引 B+ 树查找,定位到主键或数据页,再回表(若非覆盖索引)

所以,ANALYZE TABLE 更新统计信息、避免长期不 OPTIMIZE 导致页分裂严重,都是影响“是否走索引”的底层因素——它们不改变 SQL 写法,但会改变优化器的选择。

星耀云
版权声明:本站原创文章,由 星耀云 2026-01-09发表,共计1336字。
转载说明:转载本网站任何内容,请按照转载方式正确书写本站原文地址。本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。