非常棒的问题 👍,这属于 MySQL 性能优化的核心知识点之一。EXPLAIN 是分析 SQL 执行计划最重要的工具,而其中的 type 字段(访问类型)
能直观反映 MySQL 访问表时的效率——
它代表了 MySQL 查找数据的方式,从好到坏依次是:
system > const > eq_ref > ref > range > index > ALL
下面我为你 逐级解释每种类型的意义、典型场景、效率特点👇
🟩 1. system(最快)
- 含义:表中只有一行数据(系统表或常量表),是
const的特例。 - 特点:MySQL 在优化阶段就能直接确定结果,无需真正查询。
- 示例:
SELECT * FROM config_table; -- 只有一行 - 说明:这种情况非常少见,几乎只出现在系统常量表中。
🟩 2. const(非常快)
- 含义:通过主键或唯一索引查询到单条记录。
- 特点:优化器在编译阶段即可确定结果,不必真正扫描。
- 示例:
SELECT * FROM user WHERE id = 5; -- id 为主键 SELECT name FROM city WHERE code = 'BJ'; -- code 是唯一索引 - 说明:通常出现在主键或唯一索引等值查询中,是非常高效的类型。
🟩 3. eq_ref(每次匹配一行)
- 含义:对于**连接查询(JOIN)**中,被驱动表通过主键或唯一索引与外表进行匹配。
- 特点:外层表的每一行,内层表只匹配一行。
- 示例:
SELECT * FROM orders o JOIN users u ON o.user_id = u.id; -- u.id 是主键或唯一索引 - 说明:通常出现在多表连接中,性能几乎等同于 const。
🟨 4. ref(普通索引等值匹配)
- 含义:使用普通索引(非唯一索引)进行等值查询。
- 特点:可能匹配多行。
- 示例:
SELECT * FROM employee WHERE dept_id = 3; -- dept_id 是普通索引 - 说明:MySQL 会通过索引快速定位多个匹配的记录,然后回表取数据。
🟧 5. range(范围扫描)
- 含义:使用索引进行范围查找,如
>,<,BETWEEN,IN。 - 特点:扫描部分索引范围,而不是全索引。
- 示例:
SELECT * FROM orders WHERE id BETWEEN 100 AND 200; SELECT * FROM user WHERE age > 30; - 说明:效率较高,但不如 ref,因为需要扫描一段范围。
🟨 6. index(全索引扫描)
- 含义:扫描整个索引(不回表),通常是覆盖索引的场景。
- 特点:比全表扫描快,因为只扫描索引树。
- 示例:
SELECT name FROM user; -- name 是索引列 - 说明:MySQL 不需要访问数据页(只读索引),但仍要扫描所有索引项。
🟥 7. ALL(全表扫描,最慢)
- 含义:遍历整张表来查找匹配的行。
- 特点:效率最低,应尽量避免。
- 示例:
SELECT * FROM user WHERE name = 'Tom'; -- name 未建索引 - 说明:优化方向是加索引、重写 SQL、减少扫描行数。
📊 综合排序(从高效到低效)
| 类型 | 含义 | 效率 |
|---|---|---|
system | 系统常量表 | 🟩 极高 |
const | 主键/唯一索引单行匹配 | 🟩 极高 |
eq_ref | 联表主键/唯一索引匹配 | 🟩 很高 |
ref | 普通索引等值匹配 | 🟨 较高 |
range | 索引范围扫描 | 🟨 中等 |
index | 全索引扫描 | 🟧 较低 |
ALL | 全表扫描 | 🟥 最低 |
🧠 小结口诀
“System、Const神速跑,Eq_ref连表妙;
Ref范围索引巧,Index全索引,All最糟。”
是否希望我帮你画一张表格/图(从左到右展示这七种 type 的扫描范围和代价对比)?
那样在 PPT 或汇报中会非常直观。