type性能等级从优到劣为:NULL、system、const、eq_ref、ref、range、index、ALL;其中NULL表示无需访问表或索引,ALL为全表扫描最差。
Navicat执行计划中type字段的性能等级排序
navicat里看到的type值,直接反映mysql是否高效使用了索引。它不是“有没有用索引”的二值判断,而是“用得有多好”的连续谱——从system(几乎不查)到all(全表扫),性能差距可达百倍以上。
各type值的实际含义与触发条件
别只看名字,关键看什么SQL会落到哪一级:
-
system:表里只有一行数据(比如information_schema某些视图),极少见,可忽略 -
const:主键或唯一索引等值查询,且值确定(如WHERE id = 123),MySQL一次定位,最快 -
eq_ref:多表JOIN时,被驱动表用主键/唯一索引匹配,每行只找1次(如JOIN user ON order.user_id = user.id) -
ref:非唯一索引等值查询(如WHERE status = 'active',status有普通索引),可能返回多行 -
range:索引上做范围扫描(BETWEEN、IN、>、),注意IN里值太多会退化为index -
index:遍历整个索引树,没走WHERE条件筛选,只是“用索引代替全表”——和ALL一样慢,只是IO少点 -
ALL:真·全表扫描,没走任何索引,数据量一过万,响应就明显卡顿
为什么看到ref却还是慢?关键看rows和Extra
ref只是“用了索引”,不代表快。常见陷阱:
-
rows值远大于实际返回行数(比如rows=50000但只返回3行),说明索引选择性差,或者统计信息过期,ANALYZE TABLE能缓解 -
Extra里出现Using filesort或Using temporary,意味着ORDER BY/GROUP BY没走索引,即使type=ref也扛不住大数据量 - 联合索引顺序错位:
WHERE a = ? AND b = ?配(b, a)索引,type可能是ref,但key_len会变短,实际只用到第一个字段
优化目标不是“消灭ALL”,而是让type匹配查询意图
强行加索引不一定对。比如日志表按时间范围查,type=range就是合理结果;而用户表按昵称模糊搜LIKE '%关键词%',type=ALL是必然的——这时候该想的是全文索引或ES,不是硬套B+树索引。
真正容易被忽略的是index类型:它看起来“走了索引”,实则和ALL一样扫描全部数据页,只是不读数据行本身。只要看到type=index,第一反应应该是“这个索引是不是根本没被WHERE条件用上?”











