Explain 是诊断 MySQL 查询性能问题最直接的工具,能通过 type=ALL、key=NULL、rows 接近总行数等信号识别全表扫描,并结合 possible_keys、Extra 等字段分析索引失效原因,如最左前缀不匹配、隐式转换、前导通配符、OR 条件失衡或选择性差等。

Explain 是诊断 MySQL 查询性能问题最直接的工具,尤其能快速识别是否发生全表扫描,进而定位索引为何没被用上。关键不在于看有没有 type=ALL,而在于结合 key、possible_keys、rows、Extra 等字段,还原优化器的真实决策逻辑。
一眼识别全表扫描:重点盯住 type 和 key 字段
执行 EXPLAIN SELECT ... 后,重点关注两列:
-
type显示为ALL—— 这是最明确的全表扫描信号,表示 MySQL 遍历了整张表的每一行; -
key为NULL(且possible_keys也不为空)—— 表明有可用索引,但优化器主动弃用了它; -
rows值极大(接近或等于表总行数),即使type不是ALL(比如index),也可能实际扫描了大量数据,需警惕。
索引失效的五大常见原因与 Explain 对应表现
不是建了索引就一定生效。以下情况在 Explain 中有典型痕迹:
-
最左前缀未匹配:联合索引
(a,b,c),查询条件只有WHERE b = ?或WHERE c = ?,possible_keys可能列出该索引,但key为NULL,Extra里看不到Using index; -
对索引列做函数/运算/类型隐式转换:如
WHERE YEAR(create_time) = 2024或WHERE mobile = 13800138000(mobile 是 VARCHAR),key必为NULL,Extra可能出现Using where但无索引加速; -
使用了不支持索引的模糊查询:
WHERE name LIKE '%abc'(前导通配符),key为空,type=ALL;LIKE 'abc%'则可能走索引,type变为range; -
OR 条件中部分字段无索引:如
WHERE a = 1 OR b = 2,仅a有索引,MySQL 常放弃索引走全表扫描,key=NULL,type=ALL; -
数据分布倾斜导致优化器误判:某列索引选择性极差(如性别字段),优化器估算用索引比全表扫描更慢,
possible_keys有该索引,但key=NULL,Extra可能含Using where。
验证与修复:从 Explain 出发的实操步骤
发现异常后,不要急着改 SQL,按顺序验证:
- 用
SHOW INDEX FROM table_name确认索引真实存在、字段顺序、是否为前缀索引; - 检查查询字段类型与索引列是否严格一致(比如 INT vs VARCHAR、带不带空格、大小写敏感性);
- 用
SELECT COUNT(*)和COUNT(*) WHERE 列 = 值估算该值的选择性,判断优化器弃用索引是否合理; - 强制指定索引测试:
EXPLAIN SELECT ... FROM t USE INDEX (idx_name) WHERE ...,观察rows是否显著下降; - 必要时重写 SQL(如拆 OR 为 UNION ALL)、添加复合索引、或用
ANALYZE TABLE更新统计信息。
别忽略 Extra 字段里的关键线索
Extra 是解释“为什么没走索引”或“走索引但效率低”的最后一环:
-
Using filesort:排序无法利用索引,可能因ORDER BY字段不在索引中或顺序不匹配; -
Using temporary:需要临时表(常出现在 GROUP BY + 非索引字段、DISTINCT、子查询等),往往伴随性能瓶颈; -
Using index condition:启用了 ICP(索引条件下推),说明部分过滤下推到存储引擎层,是好现象; -
Using where; Using index:覆盖索引 + 索引过滤,效率最高;若只有Using where,说明回表了,但至少走了索引。











