mysql性能优化-查询执行计划分析(EXPLAIN)
EXPLAIN命令用于显示 MySQL 如何执行SELECT查询。它提供了关于表如何被扫描、使用了哪些索引、表之间的连接顺序、连接类型等关键信息。通过EXPLAIN命令,开发者可以深入了解查询的执行方式,从而找出可以优化的地方。基本语法MySQL 将会返回查询执行的详细计划。可以用于SELECT查询,以及包含SELECT的INSERTUPDATEDELETE语句。EXPLAIN是 MySQL 查询
在 MySQL 性能优化 中,分析查询的执行计划是一个至关重要的步骤,EXPLAIN
命令可以帮助我们理解查询的执行过程,找出可能的性能瓶颈,并采取优化措施。通过 EXPLAIN
返回的信息,我们可以了解 MySQL 如何执行 SQL 语句,包括使用了哪些索引、表的访问顺序以及执行代价等。
一、什么是 EXPLAIN
EXPLAIN
命令用于显示 MySQL 如何执行 SELECT
查询。它提供了关于表如何被扫描、使用了哪些索引、表之间的连接顺序、连接类型等关键信息。通过 EXPLAIN
命令,开发者可以深入了解查询的执行方式,从而找出可以优化的地方。
基本语法:
EXPLAIN SELECT * FROM table WHERE conditions;
MySQL 将会返回查询执行的详细计划。可以用于 SELECT
查询,以及包含 SELECT
的 INSERT
、UPDATE
、DELETE
语句。
二、EXPLAIN 输出的字段解释
使用 EXPLAIN
运行查询时,MySQL 会返回多列信息,帮助我们分析查询的执行计划。常见的字段包括:
字段 | 解释 |
---|---|
id | 查询中执行步骤的标识符。每个步骤有唯一的 id 。值越大优先级越高。 |
select_type | 查询的类型,表示查询是简单查询还是复杂查询(如子查询、联合查询等)。 |
table | 显示被查询的表。 |
type | 表的访问方式,表示 MySQL 如何查找表中的行。 |
possible_keys | 显示 MySQL 在查询中可能使用的索引。 |
key | 实际使用的索引。 |
key_len | 使用索引的字节长度,反映索引字段的长度。 |
ref | 显示索引列与哪一列进行了比较。 |
rows | MySQL 估计查询时扫描的行数。 |
filtered | 满足查询条件的行占扫描行的百分比。 |
Extra | 附加信息,描述查询执行的细节,如是否使用了文件排序、临时表等。 |
三、EXPLAIN 字段详解与优化
1. id:执行顺序
id
字段表示查询执行步骤的标识符。id
的值越大,优先执行的顺序越靠后,通常用于复杂查询(如子查询、联合查询)。id
相同的步骤表示可以并行执行,不同 id
的步骤按照 id
值从小到大依次执行。
2. select_type:查询类型
select_type
字段表示查询的类型,有以下几种常见类型:
- SIMPLE:简单的
SELECT
查询,不包含子查询或联合查询。 - PRIMARY:最外层的查询。
- SUBQUERY:子查询。
- DERIVED:派生表,通常是子查询在
FROM
中的表现形式。 - UNION:联合查询的第二个及以后的
SELECT
。
优化建议:
- 尽量避免过多的子查询,子查询可以转为
JOIN
操作以提高性能。 - 尽量减少复杂的联合查询和嵌套查询。
3. table:查询的表
table
字段表示当前执行计划操作的是哪张表。如果是子查询或派生表,该字段会显示派生表的别名。
4. type:访问类型
type
字段是 EXPLAIN
中最重要的部分之一,显示了 MySQL 如何查找表中的行。它反映了查询效率的高低。type
从好到差的顺序如下:
类型 | 解释 |
---|---|
system | 表只有一行记录,非常快速。 |
const | 表中只有一行匹配。通常用于主键或唯一索引。 |
eq_ref | 针对主键或唯一索引的连接查询,效率较高。 |
ref | 非唯一索引的连接查询,匹配多行记录。 |
range | 使用索引的范围查询。 |
index | 扫描索引的全部内容,比全表扫描要高效。 |
ALL | 全表扫描。性能最差。 |
优化建议:
- 尽量避免
ALL
类型的全表扫描。全表扫描通常意味着没有使用索引,应该通过创建索引或优化查询条件来避免。 - 优化查询以使用
const
、eq_ref
等高效的访问类型。 - 使用
range
来处理范围查询,确保索引能够加速范围检索。
5. possible_keys:可能使用的索引
possible_keys
字段显示 MySQL 在执行查询时可能使用的索引。如果该字段为空,说明 MySQL 没有找到可用的索引,通常这是性能瓶颈的信号。
优化建议:
- 确保在查询条件中的列上创建合适的索引,尤其是
WHERE
、JOIN
或ORDER BY
语句涉及的列。
6. key:实际使用的索引
key
字段表示 MySQL 实际使用的索引。这个字段是索引优化的关键,EXPLAIN
让你知道 MySQL 是否使用了正确的索引。
优化建议:
- 如果
possible_keys
有值,而key
字段为空,说明 MySQL 选择不使用索引,可以通过FORCE INDEX
强制使用索引,或者调整索引设计和查询条件,使索引更具选择性。
7. key_len:索引长度
key_len
显示 MySQL 实际使用的索引的字节长度。这个字段帮助你判断索引是否充分利用。例如,对于组合索引,key_len
可以帮助你了解索引是否使用了所有列。
优化建议:
key_len
越短,查询效率越高。确保只为必要的列创建索引,避免使用过多的索引列。
8. ref:索引比较列
ref
字段表示索引列与哪些列进行了比较。例如,当 ref
显示为 const
时,表示索引与常量值进行了比较。如果是多表查询,ref
字段显示的是连接使用的列。
优化建议:
- 尽量在
WHERE
子句中使用常量值或主键列,以提高查询效率。
9. rows:扫描的行数
rows
字段表示 MySQL 估计需要扫描的行数,数值越大,查询的代价越高。rows
是一个估算值,基于表统计信息。
优化建议:
- 优化查询条件和索引,尽量减少
rows
值。 - 定期使用
ANALYZE TABLE
或OPTIMIZE TABLE
来更新表统计信息,确保 MySQL 的估算值准确。
10. Extra:附加信息
Extra
字段提供了额外的查询信息,通常提示我们是否可以进一步优化查询。常见的 Extra
信息包括:
- Using index:查询只使用了索引(覆盖索引),无需回表。
- Using where:查询使用了
WHERE
条件过滤。 - Using temporary:MySQL 在查询中使用了临时表,通常出现在复杂的
ORDER BY
、GROUP BY
操作中。 - Using filesort:MySQL 使用了文件排序,表示没有使用索引进行排序,性能较差。
优化建议:
- 避免 Using temporary:临时表会增加磁盘 I/O,建议优化查询或使用适当的索引来减少临时表的使用。
- 避免 Using filesort:尽量使用索引来优化排序操作,避免文件排序。
四、EXPLAIN 优化示例
1. 使用索引优化查询
假设有一个 employees
表:
CREATE TABLE employees (
id INT PRIMARY KEY,
name VARCHAR(50),
department_id INT,
salary DECIMAL(10, 2),
INDEX idx_department (department_id)
);
查询某个部门的员工:
EXPLAIN SELECT * FROM employees WHERE department_id = 5;
如果索引 idx_department
被使用,EXPLAIN
中的 key
字段会显示 idx_department
,而 type
字段为 ref
,表示
使用了索引进行高效查询。
2. 避免全表扫描
查询所有工资超过一定值的员工:
EXPLAIN SELECT * FROM employees WHERE salary > 50000;
如果 salary
列上没有索引,type
会显示 ALL
,表明 MySQL 进行了全表扫描。可以通过为 salary
列添加索引来优化查询:
CREATE INDEX idx_salary ON employees (salary);
再运行 EXPLAIN
,可以看到 type
字段变为 range
,表示索引范围查询,大大提升查询效率。
五、EXPLAIN 的使用建议与限制
- 复杂查询优先分析:对复杂查询(如包含
JOIN
、GROUP BY
、子查询等)使用EXPLAIN
,优先优化这些查询,因为它们的性能问题更为常见。 - 持续监控:定期使用
EXPLAIN
分析关键查询的执行计划,随着数据量的增长,查询计划可能发生变化,需要持续优化。 - 了解索引的局限性:索引是查询优化的主要工具,但不当使用索引(如在低选择性的列上建立索引)可能反而会降低性能。
六、总结
EXPLAIN
是 MySQL 查询优化中非常重要的工具,通过它我们可以深入了解查询执行的过程,找到性能瓶颈,并通过索引、查询重构等手段进行优化。通过分析 EXPLAIN
的输出,可以帮助开发者了解 MySQL 查询的执行顺序、使用的索引、扫描的行数等信息,并为下一步的优化提供有力依据。

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)