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

来源:这里教程网 时间:2026-02-28 20:38:23 作者:

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

MySQL 不会主动告诉你“用了哪个索引”,但

EXPLAIN
会把优化器的决策摊开给你看。在 SQL 前加
EXPLAIN
,重点关注
type
key
rows
Extra
这几列:

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

注意:仅

key
非空不等于“高效”,还要结合
type
rows
综合判断。

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

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

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

这些不是语法错误,SQL 能正常执行,但执行计划里

key
会是
NULL
type
变成
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 写法,但会改变优化器的选择。

相关推荐