type 是性能第一判断依据,它直接反映mysql优化器选择的执行路径:const最快,all最差,需结合key_len、filtered、extra等字段综合分析。

type 字段直接告诉你这条 SQL 是怎么查数据的,性能好坏一眼就能判——它不是“参考指标”,而是执行路径的硬编码。
type 为什么是性能第一判断依据
MySQL 优化器最终决定用哪种方式捞数据,type 就是那个决策结果的标签。它不看语句写得多漂亮,只看实际走哪条路:是从主键直接跳到一行(const),还是扫完整个索引(index),甚至干脆全表扫(ALL)。
-
system和const几乎不用优化,只要条件写对、索引建对,就天然快 -
eq_ref和ref看连接字段或 WHERE 条件是否命中唯一索引 / 普通索引 -
range意味着用了索引但没“点中”,比如写了WHERE created_at > '2025-01-01',范围越宽,rows越大 -
index是全索引扫描,比ALL略好(至少不读数据行),但仍是警告信号 -
ALL表示没走任何索引,必须立刻排查:缺索引?索引失效(如函数包裹、类型隐式转换)?还是查询条件根本没法用索引?
ref 和 eq_ref 的区别到底在哪
两者都走索引等值匹配,但约束强度不同:前者允许返回多行,后者强制最多一行。
-
eq_ref要求被驱动表的关联字段是PRIMARY KEY或UNIQUE KEY,且 JOIN 条件是等值(=),例如:JOIN users ON orders.user_id = users.id(users.id是主键) -
ref只要普通索引就行,比如orders.status有索引,WHERE status = 'pending'就会是ref;或者JOIN时用的是非唯一外键,也会降级为ref - 常见陷阱:明明建了唯一索引,但 JOIN 条件写成
orders.user_id = COALESCE(users.id, 0),函数导致索引失效,type就掉回ALL或index
range 类型背后的真实成本
range 看起来比 ALL 好,但它常被误判为“已优化”。实际上,它的代价取决于范围大小和索引选择性。
-
IN列表过长(比如WHERE id IN (1,2,...,500))可能让优化器放弃索引,转而选ALL -
BETWEEN或>查询,如果范围覆盖 80% 以上数据,rows接近表总行数,这时建索引意义不大,不如考虑分区或业务拆分 -
key_len值偏小(比如联合索引只用到第一列),说明后续列无法参与过滤,filtered字段会很低,实际扫描行数远超预期
type 显示 const 却慢?先看 Extra 字段
const 本身代表极快,但如果 Extra 出现 Using filesort 或 Using temporary,说明排序或分组被迫在内存/磁盘做,速度瓶颈不在查找而在后续操作。
- 例如:
EXPLAIN SELECT * FROM users WHERE id = 123 ORDER BY created_at DESC,即使type是const,若created_at没索引,就会触发Using filesort - 联合索引可以缓解:把
id和created_at组成(id, created_at)索引,ORDER BY就能复用索引顺序 -
const+Using where是正常现象;但const+Using index condition表明用了 ICP(索引条件下推),是加分项
真正难的不是看懂 type 是什么,而是理解它为什么是这个值——背后是索引结构、查询条件写法、统计信息准确度三者共同作用的结果。一个 ref 可能比 range 更慢,如果前者要回表 10 万次,后者用覆盖索引只扫 5000 行。别只盯 type,把它当起点,不是终点。











