如何使用 MySQL 的 EXPLAIN 语句进行查询分析?
如何使用 MySQL 的 EXPLAIN 语句进行查询分析?
EXPLAIN 是 MySQL 提供的分析 SQL 查询执行计划的工具,用于了解查询语句的执行过程,帮助优化查询性能。
1. EXPLAIN 的使用方法
基本语法
EXPLAIN SELECT * FROM table_name WHERE conditions;
或者:
EXPLAIN FORMAT=JSON SELECT * FROM table_name WHERE conditions;
EXPLAIN会返回查询的执行计划信息,包括涉及的表、索引的使用情况、扫描方式等。FORMAT=JSON提供结构化的 JSON 格式信息,包含更详细的执行计划内容。
2. EXPLAIN 输出的字段解释
EXPLAIN 的输出包含多个字段,常见字段如下:
| 字段名 | 说明 |
|---|---|
| id | 查询中每个操作的标识符,查询的执行顺序从大到小。 |
| select_type | 查询类型,如简单查询、子查询、联合查询等(SIMPLE、PRIMARY、SUBQUERY 等)。 |
| table | 当前查询操作涉及的表名。 |
| partitions | 表示使用的分区(如果有分区表)。 |
| type | 访问类型,表示查询操作的效率,类型从好到差依次为:system > const > eq_ref > ref > range > index > ALL。 |
| possible_keys | 查询可能使用的索引。 |
| key | 查询实际使用的索引。 |
| key_len | 使用索引的字节长度,反映索引使用的精确性。 |
| ref | 表示使用索引的比较列。 |
| rows | MySQL 估计需要扫描的行数,行数越少,查询性能越高。 |
| filtered | 表示返回结果占扫描行数的百分比,值越大越好。 |
| Extra | 额外信息,如 Using index(覆盖索引)、Using where(条件过滤)、Using temporary(临时表)。 |
3. 示例分析
示例 1:简单查询
EXPLAIN SELECT * FROM orders WHERE customer_id = 1001;
输出示例:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
|---|---|---|---|---|---|---|---|---|---|
| 1 | SIMPLE | orders | ref | customer_id | customer_id | 4 | const | 10 | Using where; Using index |
- type:
ref表示使用索引访问数据。 - key: 使用了
customer_id索引。 - Extra:
Using where; Using index表示通过索引过滤数据并直接返回结果,性能较优。
示例 2:范围查询
EXPLAIN SELECT * FROM orders WHERE order_date BETWEEN '2024-01-01' AND '2024-12-31';
输出示例:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
|---|---|---|---|---|---|---|---|---|---|
| 1 | SIMPLE | orders | range | order_date | order_date | 3 | NULL | 1500 | Using where |
- type:
range表示索引范围扫描。 - rows: 扫描约 1500 行,查询效率较高。
- Extra:
Using where表示查询条件在索引范围内过滤数据。
示例 3:子查询
EXPLAIN SELECT * FROM orders WHERE customer_id IN (SELECT id FROM customers WHERE country = 'USA');
输出示例:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
|---|---|---|---|---|---|---|---|---|---|
| 1 | PRIMARY | orders | ref | customer_id | customer_id | 4 | const | 500 | Using where |
| 2 | SUBQUERY | customers | range | country | country | 20 | NULL | 100 | Using where; Using index |
- id: 子查询的
id为 2,主查询的id为 1,表示子查询先执行。 - Extra:
Using index表示子查询的结果通过索引直接返回,性能较优。
示例 4:JOIN 查询
EXPLAIN SELECT o.* FROM orders o JOIN customers c ON o.customer_id = c.id WHERE c.country = 'USA';
输出示例:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
|---|---|---|---|---|---|---|---|---|---|
| 1 | SIMPLE | c | ref | country | country | 20 | const | 100 | Using where |
| 1 | SIMPLE | o | ref | customer_id | customer_id | 4 | c.id | 500 | Using where |
- 执行顺序: 表
c的过滤条件先执行,然后通过customer_id的索引关联表o。 - 优化建议: 确保
country和customer_id字段上有合适的索引。
4. EXPLAIN 的常见优化点
-
优先使用合适的索引
- 查看
possible_keys和key,确保查询语句能命中预期的索引。
- 查看
-
优化扫描范围
- 避免
type为ALL或index,优先通过ref、range等高效方式访问数据。
- 避免
-
减少扫描行数
- 查看
rows字段,减少扫描的行数,降低查询的 I/O 成本。
- 查看
-
消除临时表和文件排序
- 如果
Extra中出现Using temporary或Using filesort,尝试优化语句,避免使用临时表或文件排序。
- 如果
-
使用覆盖索引
- 确保查询可以通过索引直接返回所需数据,避免回表操作。
总结
EXPLAIN 是优化 MySQL 查询性能的重要工具,可以帮助我们理解查询的执行计划和潜在的性能问题。通过合理使用索引、优化查询语句、减少扫描范围,可以大幅提升查询效率。

浙公网安备 33010602011771号