完全不用担心!记不住 EXPLAIN
的输出字段是非常正常的,因为它包含的信息确实很多。这其实不是一个需要死记硬背的东西,而是一个需要理解其核心思想并通过查看来熟练使用的工具。
下面我给您一个超实用的 “三步速查指南” 和 核心字段详解,您以后遇到就翻出来看,看多了自然就熟了。
三步速查指南:如何快速判断SQL性能?
拿到一条 EXPLAIN
结果,不要一个个字段看晕了,按照这三个步骤来分析:
✅ 第一步:先看 type
列(访问类型)—— 这是最重要的指标!
这列告诉你 MySQL 如何查找数据。从好到坏排列,理想状态是尽量靠前:
类型 (值) | 含义 | 性能 | 解读 |
---|---|---|---|
system |
系统表,只有一行数据 | 最佳 | 忽略,极少见。 |
const |
通过主键或唯一索引一次就找到 | 极佳 | WHERE id = 1 ,效率最高。 |
eq_ref |
联表查询时,使用主键或唯一索引关联 | 极佳 | 常见于 A JOIN B ON A.id = B.id 。 |
ref |
使用普通非唯一索引查找 | 优秀 | WHERE name = 'Alice' (name是普通索引)。 |
range |
索引范围扫描 | 良好 | WHERE id > 100 ,BETWEEN ,IN 。 |
index |
全索引扫描 | 较差 | 比全表扫描好点,但需要扫描整个索引树。 |
ALL |
全表扫描 | 最差 | 警报! 性能杀手,需要优化。 |
您的例子解读:
type: ALL
-> 这是最坏的情况,说明MySQL正在对 com_order
表进行全表扫描,性能极差。
✅ 第二步:看 key
和 possible_keys
列(用没用索引?)
possible_keys
: 可能用到的索引(MySQL分析后认为可以用的索引列表)。key
: 实际用到的索引。如果为NULL
,说明没用到索引。
您的例子解读:
possible_keys: NULL
和 key: NULL
-> 说明这条查询没有任何合适的索引可用,这完美解释了为什么第一步的 type
是 ALL
(全表扫描)。
✅ 第三步:看 rows
和 Extra
列(扫描了多少行?有没有额外操作?)
rows
: MySQL 估算需要扫描的行数。这个值越小越好。- 您的例子解读:
rows: 2356562
-> 预计要扫描235万行!这证实了性能问题非常严重。
- 您的例子解读:
Extra
: 额外信息,非常重要,常包含优化建议。Using where
: 表示在存储引擎检索行后,MySQL服务器还需要再进行过滤。Using index
: (好信号) 表示查询只用了索引中的信息,无需回表。Using temporary
: (坏信号) 表示需要创建临时表来处理查询,常见于GROUP BY、ORDER BY。Using filesort
: (坏信号) 表示无法利用索引完成排序,需要额外的排序操作。
您的例子解读:
Extra: Using where
-> 结合全表扫描,说明MySQL从硬盘读出235万行数据后,还要在内存里一条条用你的WHERE条件去过滤。
对您这条SQL的综合分析与优化建议
结论:这是一条非常糟糕的查询,急需优化。
- 问题根源:
WHERE
条件中的列没有建立索引,导致数据库只能进行全表扫描。 - 性能影响:每次查询需要扫描约 235万行 数据,CPU和磁盘I/O压力巨大,速度极慢。
解决方案:为 WHERE
条件中的列添加索引
假设您的查询语句类似:
SELECT * FROM com_order WHERE your_column = 'some_value';
您需要为 your_column
创建索引:
ALTER TABLE com_order ADD INDEX idx_your_column (your_column);
创建索引后,再使用 EXPLAIN
查看,您会看到神奇的变化:
type
会从ALL
变为ref
(如果是等值查询)或range
(如果是范围查询)。key
会显示idx_your_column
,表示正在使用您新创建的索引。rows
会从一个巨大的数变成一个很小的数(例如1、10、100)。- 查询速度将会提升几十甚至几百倍。
总结:一张图记住核心流程
下次分析 EXPLAIN
,就按这个顺序看:
flowchart TD
A[拿到EXPLAIN结果] --> B{"第一步:看type字段"}
B --✅ const, eq_ref, ref, range --> E[✅ 性能良好]
B --⚠️ index --> F[⚠️ 有待优化]
B --❌ ALL --> C["❌ 警报!全表扫描"]
C --> D{"第二步:看key字段"}
D --NULL--> G["确认:无索引可用<br>解决方案:为WHERE条件列创建索引"]
D --有值--> H["异常:有索引却未使用<br>解决方案:检查索引是否失效<br>或查询写法问题"]
E --> I["第三步:看rows和Extra"]
I --> J["rows: 估算行数越少越好<br>Extra: 警惕Using filesort/temporary"]