explain用于分析查询执行计划,关键看type(all最差)、key与possible_keys(确认索引是否生效)、rows(预估扫描行数)和extra(如using filesort、using temporary等隐藏开销)。

直接在 SELECT 语句前加 EXPLAIN,就能看到数据库“打算怎么查”,而不是真正去执行它。重点不是看全表,而是盯住几个关键字段——它们会直接暴露慢在哪。
看 type 字段:识别访问效率高低
这是判断查询快慢最核心的指标,值从优到劣依次为:const → eq_ref → ref → range → index → ALL。
- ALL 出现就敲警钟:表示全表扫描,数据量一上去性能断崖下跌
- index 是全索引扫描,比 ALL 好但仍有优化空间
- range 表示用了索引做范围查找(如 age > 30),属合理状态
- ref 或 eq_ref 是理想情况,说明通过非唯一/唯一索引精准定位了数据行
看 key 和 possible_keys 字段:确认索引是否生效
这两个字段一起看,才能知道索引有没有被“用对”。
- key 为 NULL:没走任何索引,哪怕建了索引也可能因写法问题失效(比如对字段用函数、隐式类型转换)
- possible_keys 有值,key 为空:索引存在,但优化器认为不值得用(可能统计信息不准,或索引选择性差)
- key 显示具体索引名:说明索引被采纳,再结合 type 和 rows 判断是否高效
看 rows 字段:估算扫描代价
这个数字是 MySQL 预估要检查的行数,不是返回结果数。
- 如果 rows 达到几万甚至更多,而实际只返回几十行,大概率存在过滤低效或索引未覆盖条件的问题
- 对比 WHERE 条件中的字段顺序和复合索引的列顺序:必须满足最左前缀原则,否则索引可能只用上一部分
- rows 值远大于实际匹配行数,可考虑更新统计信息(ANALYZE TABLE table_name)
看 Extra 字段:捕捉隐藏开销
这里藏着很多“悄悄吃资源”的操作,尤其注意以下信号:
- Using filesort:ORDER BY 无法利用索引排序,需额外内存或磁盘排序
- Using temporary:GROUP BY、DISTINCT 或某些 JOIN 触发临时表,I/O 和内存压力大
- Using where:正常现象,表示存储引擎返回后还要服务器层过滤
- Using index:好消息,说明走了覆盖索引,无需回表查数据











