Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MySQL EXPLAIN语法

MySQL EXPLAIN语法使用超详细详解

作者:更容易记住我

EXPLAIN作为MySQL的性能分析神器,读懂其结果是很有必要的,然而我在各种搜索引擎上竟然找不到特别完整的解读,这篇文章主要介绍了MySQL EXPLAIN语法使用的相关资料,需要的朋友可以参考下

引言

EXPLAIN 是 MySQL SQL 优化神器,用来查看 MySQL 执行计划,能清晰看到 MySQL 如何执行你的查询、是否使用索引、表关联顺序、数据扫描行数等,是排查慢查询、优化 SQL 的核心工具。

一、基础用法

1. 标准语法

-- 直接加在 SELECT/DELETE/UPDATE/INSERT 语句前面
EXPLAIN SELECT * FROM user WHERE id = 1;

-- 查看更详细的执行计划(推荐使用)
EXPLAIN ANALYZE SELECT * FROM user WHERE id = 1; -- MySQL 8.0.18+ 支持

2. 能查什么?

二、执行计划字段全解

执行 EXPLAIN 后会返回一张表,共 12+ 个关键字段,下面是最核心、必须掌握的字段:

1. id(查询执行顺序)

表示查询中执行 select 子句或操作表的顺序。

2. select_type(查询类型)

判断查询是简单查询还是复杂查询:

含义
SIMPLE简单查询(不包含子查询、union)
PRIMARY复杂查询中最外层的查询
SUBQUERY子查询(select 里面嵌套的查询)
DERIVED派生表(from 子句中的子查询)
UNIONunion 中的第二个及后面的查询
UNION RESULTunion 的结果集

3. table(涉及的表)

显示这一行数据是关于哪张表的。

4. type(访问类型 → 核心!)

SQL 优化最重要的指标,表示 MySQL 在表中找到数据的方式,性能从好到坏排序:

system > const > eq_ref > ref > range > index > ALL

优化目标:至少达到 range,最好 ref 及以上

各类型详解

5. possible_keys(可能用到的索引)

MySQL 认为可能会用于查询的索引,但最终不一定使用。

6. key(实际使用的索引)

真正命中的索引,优化核心看这个字段!

7. key_len(使用的索引长度)→ 超详细计算规则

key_len 表示 MySQL 实际使用的索引字节长度,用来判断:

计算核心公式

key_len = 字段实际字节数 + NULL标记(1字节) + 变长字段长度(2字节)

一、基础数据类型字节数

先记住常用字段固定字节:

字段类型字节数说明
tinyint1-128~127
smallint2小整数
int4普通整数
bigint8长整数
float4单精度
double8双精度
char(n)n × 字符集字节定长字符串
varchar(n)n × 字符集字节变长字符串
date3日期
datetime8日期时间
timestamp4时间戳

字符集占用字节

二、3 个额外规则(必记)

  1. 允许 NULL → +1 字节
    字段定义 DEFAULT NULL,索引会多 1 字节标记 NULL。
  2. 变长字段(varchar/varbinary)→ +2 字节
    用来存储字符串长度。
  3. 联合索引 → 多列累加计算

三、实战计算案例(一看就会)

案例 1:int 类型

age int NOT NULL        -- 索引

key_len = 4(int)+ 0(not null)= 4

age int NULL            -- 索引

key_len = 4 + 1(NULL)= 5

案例 2:char 固定字符串

name char(10) NOT NULL  utf8mb4

key_len = 10×4 + 0 = 40

name char(10) NULL      utf8mb4

key_len = 10×4 + 1 = 41

案例 3:varchar 变长字符串(最常用)

phone varchar(20) NOT NULL   utf8mb4

key_len = 20×4 + 2(变长)= 82

phone varchar(20) NULL       utf8mb4

key_len = 20×4 + 2 + 1 = 83

案例 4:联合索引(判断用了几列)
表结构:

idx_age_name(age int, name varchar(10))
age int NOT NULL
name varchar(10) NULL  utf8mb4

看到 key_len=47 → 说明联合索引两列都用上了!

四、快速计算速查表

字段定义key_len
int not null4
int null5
bigint not null8
bigint null9
varchar(20) not null utf8mb420×4+2=82
varchar(20) null utf8mb420×4+2+1=83
char(10) not null utf830
char(10) null utf831

五、key_len 核心用途(优化必用)

  1. 判断联合索引是否用满
    联合索引 idx(a,b,c)
    key_len 小 → 只用了前面 1~2 列
    key_len 大 → 全部列都命中
  2. 判断是否因为 NULL 浪费空间
  3. 判断索引是否精准命中

总结

8. ref(与索引比较的列)

显示哪个列 / 常量和索引比较,找到匹配的数据。

示例:const(常量匹配)、库名.表名.列名

9. rows(扫描行数)

MySQL 预估要扫描读取的数据行数。

10. Extra(额外重要信息)

包含很多关键优化提示,重点关注:

含义 & 优化建议
Using index✅ 覆盖索引!查询的字段刚好在索引里,无需回表(最优)
Using where使用 WHERE 条件过滤数据
Using filesort❌ 文件排序!MySQL 无法用索引排序,需额外排序(必须优化)
Using temporary❌ 使用临时表!常见于 group by /order by(必须优化)
Impossible WHEREWHERE 条件永远不成立(无意义查询)

三、实战案例:看懂执行计划

案例 1:主键查询(最优)

EXPLAIN SELECT * FROM user WHERE id = 1;

结果

✅ 完美,直接命中主键索引

案例 2:普通索引查询

EXPLAIN SELECT name FROM user WHERE phone = '13800138000';

结果

✅ 优秀,覆盖索引,无需回表

案例 3:全表扫描(最差)

EXPLAIN SELECT * FROM user WHERE age = 20;

结果

❌ 严重问题,全表扫描,必须给 age 加索引

案例 4:索引失效(文件排序)

EXPLAIN SELECT * FROM user ORDER BY address;

结果

❌ 必须给 address 加索引优化排序

四、索引失效常见场景(用 EXPLAIN 快速判断)

执行计划中 key=NULL 就是索引失效,常见原因:

1. 索引列上使用函数 / 运算

-- 失效
SELECT * FROM user WHERE YEAR(create_time) = 2024;

2. 模糊查询以 % 开头

-- 失效
SELECT * FROM user WHERE name LIKE '%张三';

3. 类型隐式转换(字符串不加引号)

-- 失效(phone 是字符串,没加引号)
SELECT * FROM user WHERE phone = 13800138000;

4. 使用 NOT IN、!=、IS NOT NULL 等

5. 联合索引不满足最左前缀原则

五、EXPLAIN 使用总结(速记)

  1. 看 type:至少达到 range,优先 ref
  2. 看 key:必须有索引,不能为 NULL
  3. 看 rows:扫描行数越少越好
  4. 看 Extra:严禁 Using filesort、Using temporary
  5. 加索引:全表扫描、索引失效时优先加合适索引

总结

EXPLAIN 是 MySQL 优化必用工具,核心看执行计划最重要指标:type(访问类型)、key(实际索引)、Extra(额外信息)

优化目标:避免全表扫描、文件排序、临时表,尽量使用覆盖索引

8.0+ 推荐用 EXPLAIN ANALYZE,能看到实际执行时间,优化更精准

到此这篇关于MySQL EXPLAIN语法使用的文章就介绍到这了,更多相关MySQL EXPLAIN语法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文