SQL执行计划解读
MySQL中的执行计划(Execution Plan)是查询优化器对SQL语句解析后生成的执行策略。通过分析执行计划,可以了解MySQL如何访问表、使用索引、进行联接等操作,有助于优化查询性能。
MySQL 提供了 EXPLAIN
命令来查看查询语句的执行计划。
如何查看执行计划
使用 EXPLAIN
或 EXPLAIN FORMAT=JSON
查看执行计划。
基本语法
EXPLAIN SELECT * FROM table_name WHERE ...;
JSON格式
EXPLAIN FORMAT=JSON SELECT * FROM table_name WHERE ...;
JSON 格式提供了更详细的信息,适用于复杂查询的深度分析。
执行计划的输出字段
1. 关键字段解释
运行 EXPLAIN
后,会返回以下常见字段:
2. 常见字段值解读
select_type
SIMPLE
: 简单查询,不包含子查询或联合查询。PRIMARY
: 最外层查询。SUBQUERY
: 子查询。DERIVED
: 派生表(子查询产生的临时表)。UNION
: 联合查询。DEPENDENT SUBQUERY
: 子查询依赖外层查询结果。
table
物理表或别名
临时表
NULL
值:当查询优化器通过某些优化技术避免了实际表访问时(如WHERE
条件被完全优化),table
字段可能显示为NULL
type(访问类型)
类型 | 描述 |
---|---|
system | 表中只有一行(system table)。性能最好。 |
const | 常量查询,例如主键或唯一索引等限制查询结果只有一行。 |
eq_ref | 联接查询中,针对主键或唯一索引的精确匹配。 |
ref | 非唯一索引扫描,返回匹配的所有行。 |
range | 范围扫描,通常用于 |
index | 全索引扫描,索引全部内容扫描,而不是按数据表扫描。 |
ALL | 全表扫描,性能最差。 |
ref
NULL,表示查询不依赖索引列的匹配,通常在全表扫描(
type=ALL
)或索引扫描(type=index
)时出现。常量值(
const
),表示索引列与一个常量值进行比较。列引用,表示索引列与另一张表的列进行比较,通常出现在表联接中,联接条件使用了索引。
常量列表(
const,const,...
),表示索引列与一组常量值进行比较,常见于IN
查询。
Extra
Using index
:表示覆盖索引,无需回表。Using where
:表示使用了 WHERE 条件过滤数据。Using temporary
:查询需要创建临时表,例如 ORDER BY 和 GROUP BY。Using filesort
:MySQL 使用外部排序,通常是内存或磁盘操作。Using join buffer
:联接时使用了缓冲区,通常表示索引未被有效利用。
示例分析
1. 简单查询
EXPLAIN SELECT * FROM employees WHERE id = 1;
输出:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | employees | const | PRIMARY | PRIMARY | 4 | const | 1 | Using index |
解释:
type = const
:主键查询。key = PRIMARY
:使用了主键索引。Extra = Using index
:覆盖索引查询,无需回表。
2. 范围查询
EXPLAIN SELECT * FROM employees WHERE age > 30;
输出:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | employees | range | age_index | age_index | 4 | NULL | 500 | Using where |
解释:
type = range
:使用范围扫描。key = age_index
:查询使用了age
列的索引。Extra = Using where
:WHERE 条件过滤数据。
3. 联表查询
EXPLAIN SELECT * FROM orders o JOIN customers c ON o.customer_id = c.id;
输出:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | customers | ALL | PRIMARY | PRIMARY | 4 | NULL | 1000 | NULL |
1 | SIMPLE | orders | ref | customer_id | customer_id | 4 | customers.id | 500 | Using index |
解释:
type = ALL
:customers
表进行了全表扫描。type = ref
:orders
表使用了外键索引扫描。联接使用了
customer_id
索引。
执行计划优化建议
优化访问类型:
避免
ALL
和index
类型,通过创建索引将访问类型优化为const
、ref
或range
。
索引优化:
确保 WHERE 子句、联接条件、ORDER BY、GROUP BY 中涉及的列使用索引。
使用覆盖索引(
Using index
),减少回表操作。
避免临时表和排序:
尽量避免
Using temporary
和Using filesort
。对排序和分组列建立索引。
分区表:
对大表使用分区,优化扫描范围。
查询重构:
拆分复杂查询,减少嵌套子查询或多表联接。
总结
MySQL 的执行计划是优化查询性能的重要工具,使用 EXPLAIN
分析 SQL 语句的执行过程,识别性能瓶颈,通过合理设计索引、重构查询语句和调整表结构来提升查询效率。