在 MySQL 中,使用 EXPLAIN(或 EXPLAIN SELECT ...)可以查看 SQL 语句的执行计划,而其中最重要的字段之一就是 type。它表示 MySQL 在执行查询时访问数据表的方式(即访问类型),也叫做 连接类型(Join Type)。
这个字段的值越靠近 ALL(全表扫描),表示性能越差;越靠近 const 或 system,表示性能越好。
🔍 type 的所有类型按性能从好到差排序如下:
级别 类型 说明
🟢 非常优 system 表仅有一行(例如 system 表),非常快
🟢 非常优 const 表中最多只有一个匹配行,通常用于主键或唯一索引查询
🟢 非常优 eq_ref 唯一索引扫描,针对每个来自前表的记录,精确匹配一条记录
🟡 较优 ref 非唯一索引扫描,返回匹配某个索引列值的所有行
🟡 中等 fulltext 使用全文索引进行全文搜索
🟠 一般 ref_or_null 类似 ref,但还包含对 NULL 值的额外查找
🟠 一般 index_merge 多个索引合并使用,MySQL 取并集/交集
🟠 一般 unique_subquery 对于某些 IN 子查询优化为唯一索引查找
🟠 一般 index_subquery 类似于上一个,但返回多值
🔴 较差 range 索引范围扫描,查找某个范围内的记录,如 BETWEEN、<、>
🔴 较差 index 全索引扫描,遍历整个索引,避免回表但数据多时性能低
🔴 最差 ALL 全表扫描,没有用到索引,性能最差
📘 类型详解
- system
表只有一行,系统表。
非常快的情况,极少见。
- const
主键或唯一索引 + 常量查询,例如:SELECT * FROM users WHERE id = 1;
最多匹配一行,MySQL 在优化阶段即确定结果。
- eq_ref
针对连接操作中的子表,使用主键/唯一索引与外部表一对一匹配。SELECT * FROM orders o JOIN users u ON o.user_id = u.id;
- ref
使用非唯一索引查找,如普通索引字段的等值查询。SELECT * FROM users WHERE name = 'Alice';
- ref_or_null
查找索引匹配某值 或 NULL 的情况。SELECT * FROM users WHERE referrer_id = 10 OR referrer_id IS NULL;
- index_merge
多个索引联合使用(并集或交集)。SELECT * FROM users WHERE age = 20 OR city = 'Beijing';
- range
索引范围扫描,比如使用 <、BETWEEN、IN。SELECT * FROM users WHERE age BETWEEN 18 AND 30;
- index
扫描整个索引,但不扫表;常见于 ORDER BY、GROUP BY。SELECT age FROM users;
- ALL
全表扫描,没有使用索引,性能最差。SELECT * FROM users WHERE age + 1 = 20;
✅ 如何优化 type?
避免出现 ALL、index 类型。
加索引:为 WHERE、JOIN、ORDER BY 中用到的字段建立合适的索引。
使用覆盖索引:避免回表操作。
避免在 WHERE 条件中对字段进行函数或表达式运算。
使用合适的连接顺序(表小的、过滤多的放前面)。
https://www.52runoob.com/archives/5401