直接在 SELECT 前加 EXPLAIN
就能看到执行计划
MySQL 不需要额外安装或开启配置,只要你的查询是
SELECT,在它前面加上
EXPLAIN关键字,立刻返回执行计划的结构化信息。这不是日志、不是慢查分析,而是优化器“打算怎么执行”的快照——注意,它不真正执行语句(除非
FROM里有子查询,那部分会被实际执行并写入临时表)。 正确写法:
EXPLAIN SELECT * FROM user WHERE id = 123;错误写法:
EXPLAIN UPDATE ...或
EXPLAIN INSERT ...—— 这些会报语法错误,
EXPLAIN只支持
SELECT(及
DELETE/
INSERT/
REPLACE的某些变体,但生产中几乎不用,别依赖) 别用
EXPLAIN FORMAT=JSON初学:虽然更详细,但字段嵌套深、可读性差,先盯住默认表格输出的 10 列,比 JSON 更快定位问题
type
字段决定查询快不快,优先看它是不是 ALL
或 index
type是执行计划里最敏感的性能信号灯。它告诉你 MySQL 怎么“找数据”:是从整张表扫(
ALL),还是走索引跳(
ref、
eq_ref),或是只查一行(
const)。从差到好排序是:
ALL→
index→
range→
ref→
eq_ref→
const。
type=ALL:全表扫描,意味着没走索引,或者
WHERE条件用了函数/隐式转换(比如
WHERE DATE(create_time) = '2025-01-01'),哪怕字段上有索引也废了
type=index:比
ALL稍好,但仍是遍历整个索引树,常见于
SELECT count(*) FROM t(无
WHERE)或只查索引覆盖字段但没加
WHERE条件 目标至少是
range:说明用了索引做范围查找(
>=、
BETWEEN、
IN),再往上
ref(等值查非唯一索引)和
eq_ref(主键/唯一索引关联)才是健康状态
key
和 possible_keys
对不上?说明优化器放弃了你建的索引
possible_keys是“候选索引列表”,
key是“最终选中的那个”。两者不一致很常见,但值得深挖原因: 索引选择性太低:比如给性别字段(只有 'M'/'F')建了索引,优化器发现走索引还不如全表扫描快,就弃用 统计信息过期:
ANALYZE TABLE t;强制刷新行数、索引分布等元数据,有时能“唤醒”被忽略的索引
WHERE条件顺序和联合索引顺序不匹配:比如索引是
(a,b,c),但查询写了
WHERE b = 1 AND c = 2,
a没出现,这个索引就无法使用前缀匹配,
key会是
NULL别盲目加索引:
possible_keys里出现多个索引,反而可能说明表设计或查询逻辑有问题(比如字段冗余、条件拆分不当)
别漏看 Extra
里的隐藏开销
Extra是执行计划的“备注栏”,里面藏着真实性能杀手:
Using filesort:MySQL 要额外排序,通常因为
ORDER BY字段没走索引,或排序字段和
WHERE字段不在同一索引里
Using temporary:创建了临时表,常见于
GROUP BY+
ORDER BY字段不一致、或子查询结果需缓存
Using index(注意没有
filesort或
temporary):这是好消息,表示走了“覆盖索引”,不用回表查数据行
Using where:正常现象,说明 MySQL 在存储引擎层之后又做了一次过滤(比如索引只能过滤部分条件,剩余条件靠 Server 层判断)
真正容易被忽略的是:
Using filesort和
Using temporary同时出现,往往意味着查询已脱离可控范围——这时光调索引没用,得重审业务逻辑是否允许分页改写、聚合下推或结果集裁剪。
