Skip to content

MySQL EXPLAIN 使用指南

概述

EXPLAIN 语句用于分析 SQL 查询的执行计划,帮助开发者理解 MySQL 如何执行查询并进行性能优化。

来源: https://dev.mysql.com/doc/refman/8.0/en/explain.html


基本语法

TRADITIONAL 格式(默认)

sql
EXPLAIN SELECT Name FROM country WHERE Code LIKE 'A%';

TREE 格式

sql
EXPLAIN FORMAT=TREE SELECT Name FROM country WHERE Code LIKE 'A%';

JSON 格式(最详细)

sql
EXPLAIN FORMAT=JSON SELECT Name FROM country WHERE Code LIKE 'A%';

EXPLAIN 输出列详解

列名说明
id查询的序号,表示执行顺序
select_type查询类型(SIMPLE、PRIMARY、SUBQUERY 等)
table表名
partitions使用的分区
type连接类型/访问类型
possible_keys可能使用的索引
key实际使用的索引
key_len使用的索引长度(字节)
ref与索引比较的列或常量
rows估计需要检查的行数
filtered行过滤百分比
Extra额外信息

来源: https://dev.mysql.com/doc/refman/8.0/en/explain-output.html


连接类型(按性能从优到劣排序)

类型说明性能
system表只有一行记录(const 的特例)⭐⭐⭐⭐⭐
const最多匹配一行,通常为主键或 UNIQUE 索引查询⭐⭐⭐⭐⭐
eq_ref每个组合读取一行,使用 PRIMARY KEY 或 UNIQUE NOT NULL 索引⭐⭐⭐⭐
ref非唯一索引查询,可能返回多行⭐⭐⭐
range索引范围扫描⭐⭐⭐
index全索引扫描⭐⭐
ALL全表扫描(最差)

来源: https://dev.mysql.com/doc/refman/8.0/en/explain-output.html来源: https://dev.mysql.com/doc/refman/8.0/en/dynindex-jointype.html

Const 示例

sql
SELECT * FROM _tbl_name_ WHERE _primary_key_=1;
SELECT * FROM _tbl_name_
  WHERE _primary_key_part1_=1 AND _primary_key_part2_=2;

Eq_ref 示例

sql
SELECT * FROM _ref_table_,_other_table_
  WHERE _ref_table_._key_column_=_other_table_._column_;

Extra 列常见值

说明
Using index覆盖索引,无需回表查询
Using where使用了 WHERE 条件过滤
Using where with pushed condition条件推送优化
Using temporary使用了临时表(需优化)
Using filesort使用了文件排序(需优化)
Backward index scan反向索引扫描

来源: https://dev.mysql.com/doc/refman/8.0/en/engine-condition-pushdown-optimization.html来源: https://dev.mysql.com/doc/refman/8.0/en/descending-indexes.html


实例解析

示例 1:范围查询

sql
EXPLAIN SELECT a, b FROM t1 WHERE a < 2\G

输出:

*************************** 1. row ***************************
         id: 1
select_type: SIMPLE
      table: t1
       type: range
possible_keys: a
        key: a
    key_len: 5
        ref: NULL
       rows: 2
     Extra: Using where with pushed condition

来源: https://dev.mysql.com/doc/refman/8.0/en/engine-condition-pushdown-optimization.html

示例 2:ORDER BY 使用索引

sql
EXPLAIN SELECT * FROM t1 ORDER BY a ASC\G

输出:

*************************** 1. row ***************************
         id: 1
select_type: SIMPLE
      table: t1
   partitions: NULL
       type: index
possible_keys: NULL
        key: a_desc_b_asc
    key_len: 10
       rows: 1
   filtered: 100.00
     Extra: Backward index scan; Using index

来源: https://dev.mysql.com/doc/refman/8.0/en/descending-indexes.html

示例 3:复合索引查询

sql
EXPLAIN SELECT COUNT(*) FROM t1 WHERE i1 = 3 AND d = '2000-01-01'\G

输出:

*************************** 1. row ***************************
         id: 1
select_type: SIMPLE
      table: t1
       type: ref
possible_keys: PRIMARY,k_d
        key: k_d
    key_len: 8
        ref: const,const
       rows: 1
     Extra: Using index

来源: https://dev.mysql.com/doc/refman/8.0/en/index-extensions.html


最佳实践

  1. 避免 type=ALL:全表扫描通常是性能瓶颈
  2. 关注 rows:与 EXPLAIN ANALYZE 的实际结果对比
  3. 优化 Extra:尽量避免 Using temporaryUsing filesort
  4. 使用合适的索引:确保 key 列显示预期的索引

来源: https://dev.mysql.com/doc/refman/8.0/en/explain-output.html


文档生成时间:2026-05-19数据来源:MySQL 8.0 Reference Manual

更新于:

note