type字段是判断SQL性能的判决项,直接反映MySQL实际扫描数据的方式:const最快(主键等值查),ref次之(非唯一索引等值),range为范围扫描,index需遍历整棵索引树,ALL为全表扫描最慢。

EXPLAIN 的 type 字段是判断查询快不快的最直接依据,不是“参考项”,而是“判决项”——看到它就基本知道这句 SQL 能不能扛住线上流量。
为什么 type 值比 rows 或 key 更优先看?
因为 rows 是估算值,InnoDB 下常不准;key 只告诉你用了哪个索引,但没说怎么用;而 type 直接暴露 MySQL 实际扫描数据的方式——是精准捞 1 行,还是扫完整个索引树,甚至全表扫。
它背后对应的是 B+ 树的遍历路径深度和范围,直接影响 I/O 次数。比如:
-
const:主键等值查,一次定位,磁盘读 1 次(或命中 buffer pool) -
ref:普通索引等值查,可能回表多次,I/O 上升 2–5 倍 -
ALL:没走索引,每行都得读,数据量翻倍,耗时往往翻 10 倍以上
type 从好到差的真实排序和典型触发场景
官方文档写的顺序是 system > const > eq_ref > ref > range > index > ALL,但实际业务中你几乎不会遇到 system(只用于极少数系统表),真正高频且关键的是后 5 种:
-
const:WHERE 条件命中主键或唯一索引,且值是常量,例如WHERE user_id = 123或WHERE phone = '138xxxx'(phone 有 UNIQUE 约束) -
eq_ref:多表 JOIN 时,被驱动表的 ON 条件用了主键/唯一索引,例如JOIN orders o ON u.user_id = o.user_id,且orders.user_id是主键或有 UNIQUE 索引 -
ref:WHERE 或 JOIN 条件用了非唯一索引,例如WHERE status = 'paid'(status 是普通索引),或JOIN时用的是普通索引字段 -
range:用了索引做范围扫描,如WHERE created_at > '2025-01-01'、WHERE id IN (1,2,3)、WHERE amount BETWEEN 100 AND 500 -
ALL:没走任何索引,或者虽然有索引但优化器判定不走(比如 WHERE 条件对字段用了函数:WHERE DATE(created_at) = '2025-01-01')
容易被忽略的三个陷阱
很多同学看到 type=ref 就以为“有索引,没问题”,其实掉坑里了:
- 联合索引只用左前缀:建了
INDEX idx_user_status ON orders(user_id, status),但查询写成WHERE status = 'paid'→type=ALL,因为没用上user_id,索引失效 -
ref和range看似都“走了索引”,但range如果范围过大(比如WHERE id > 1000查了 90% 的数据),实际性能可能比ref还差 -
Extra字段里出现Using filesort或Using temporary时,即使type=ref,也大概率意味着排序/分组没走索引,需要额外计算资源
真正要盯死的,不是“有没有索引”,而是 type 是否稳定落在 const、eq_ref 或严格受限的 ref 上;一旦滑到 range 以下,就得立刻查 key_len 和 Extra 配合诊断——type 是信号灯,但亮黄灯时,光看灯不够,得打开引擎盖。


















