news 2026/5/1 2:04:04

Explain关键字?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Explain关键字?

EXPLAIN 关键字:MySQL 查询执行计划的 “透视镜”

你想深入了解EXPLAIN关键字,它是 MySQL 中分析查询性能、排查索引失效、优化 SQL 的核心工具 —— 通过EXPLAIN可以 “看透” MySQL 优化器如何执行你的 SQL 语句,包括是否使用索引、扫描行数、连接方式等关键信息,无需实际执行查询就能定位性能问题。

下面我会从基本用法输出字段详解实战案例进阶用法四个维度,把EXPLAIN讲透,让你能独立分析任意 SQL 的执行计划。

一、EXPLAIN 基本用法

1. 核心作用

  • 显示 MySQL 执行 SQL 时的执行计划(而非执行结果);
  • 告诉我们:SQL 将如何扫描表、是否使用索引、扫描多少行、表之间如何连接等;
  • 支持SELECTDELETEINSERTUPDATE(MySQL 8.0+),最常用的是SELECT

2. 基础语法

-- 最基础用法:分析SELECT语句 EXPLAIN SELECT * FROM user WHERE name = '张三'; -- 简写(效果相同) DESC SELECT * FROM user WHERE name = '张三'; -- MySQL 8.0+支持分析UPDATE/DELETE EXPLAIN UPDATE user SET age = 21 WHERE id = 1;

执行后会返回一个表格(通常 1 行或多行,对应多表连接),每行包含 12 个字段(MySQL 5.7+),每个字段都有明确的性能含义。

二、EXPLAIN 输出字段详解(按重要性排序)

为了方便理解,先给出一个典型的执行计划示例:

EXPLAIN SELECT id, name FROM user WHERE name = '张三';

输出结果(核心字段):

idselect_typetabletypepossible_keyskeykey_lenrefrowsExtra
1SIMPLEuserrefidx_nameidx_name62const2Using index

下面逐个解析每个字段的含义,重点标注核心关注项

1. id:查询的执行顺序标识

  • 含义:表示查询中执行子查询 / 表连接的顺序,数字越大越先执行;
  • 规则
    • 相同 id:按从上到下顺序执行(多表连接);
    • 不同 id:id 值越大,执行优先级越高;
    • NULL:表示这是一个临时表 / 汇总结果(如GROUP BY的临时表)。
  • 示例
    -- 子查询,id=2先执行,再执行id=1 EXPLAIN SELECT * FROM user WHERE id = (SELECT id FROM order WHERE order_no = 'O123');

2. select_type:查询类型(判断查询复杂度)

核心值说明(按常见程度排序):

含义
SIMPLE简单查询(无子查询、无 UNION),最常见
PRIMARY主查询(包含子查询 / UNION 时,外层查询的类型)
SUBQUERY子查询(内层查询,不依赖外层)
DERIVED派生表(FROM 中的子查询,MySQL 会先执行并生成临时表)
UNIONUNION 中的第二个及以后的查询
UNION RESULTUNION 的最终结果集

3. table:当前行对应的表 / 临时表

  • 显示执行计划对应的表名(如userorder);
  • 若为派生表,显示derivedN(N 为 id 值);
  • 若为 UNION 结果,显示unionM,N(M、N 为 id 值)。

4. type:访问类型(核心!判断索引是否生效)

含义:MySQL 扫描表中数据的方式,是判断查询性能的最核心指标,从优到劣排序如下:

类型含义性能等级说明
system表只有 1 行数据(系统表),极致优化(几乎遇不到)最优特殊情况,比 const 更好
const通过主键 / 唯一索引查询,最多匹配 1 行最优WHERE id = 1
eq_ref多表连接时,被驱动表通过主键 / 唯一索引匹配(如JOIN t2 ON t1.id=t2.id优秀关联查询的理想类型
ref通过非唯一索引匹配,返回多行(如WHERE name = '张三'良好索引生效的常见类型
ref_or_null类似 ref,但包含 NULL 值查询(如WHERE name = '张三' OR name IS NULL良好略逊于 ref
range索引范围扫描(如WHERE id BETWEEN 1 AND 10IN (1,2,3)一般索引生效,但扫描范围较大
index扫描整个索引树(未回表,如覆盖索引)较差比 ALL 好,但仍扫描全索引
ALL全表扫描(Full Table Scan)最差索引失效,性能暴跌

核心判断

  • ✅ 理想情况:const/eq_ref/ref(索引高效生效);
  • ⚠️ 需要优化:range(尽量缩小范围);
  • ❌ 必须优化:index/ALL(索引失效,全表 / 全索引扫描)。

5. possible_keys:可能使用的索引

  • 含义:MySQL 优化器认为该查询可能用到的索引列表(仅为候选,不一定实际使用);
  • 若为NULL:表示没有可用的索引(大概率会全表扫描)。

6. key:实际使用的索引(核心!)

  • 含义:MySQL 优化器最终选择的索引名称;
  • 若为NULL:表示未使用任何索引(索引失效);
  • 重点:possible_keys有值但keyNULL,说明优化器判断走索引成本更高,主动放弃(如匹配行数太多)。

7. key_len:使用的索引长度(字节)

  • 含义:表示 MySQL 使用的索引字段的总长度,可用于判断联合索引的生效范围;
  • 计算规则(示例):
    • varchar(20)(utf8):20×3 + 2(字符串长度标识)= 62 字节;
    • int:4 字节;
    • 联合索引idx_name_age(name, age):若key_len=66(62+4),说明两个字段都生效;若 = 62,说明仅 name 生效。

8. ref:与索引比较的列 / 常量

  • 含义:表示与索引字段匹配的内容,分为两种:
    • const:匹配常量(如WHERE name = '张三',' 张三 ' 是常量);
    • 表名。字段名:多表连接时,匹配另一张表的字段(如t1.name = t2.name);
  • 若为NULL:表示没有使用等值匹配(如范围查询)。

9. rows:预估扫描行数(核心!)

  • 含义:MySQL 优化器预估的、执行查询需要扫描的行数(不是实际行数);
  • 数值越小越好:行数越多,说明需要扫描的数据越多,性能越差;
  • 注意:该值是基于表的统计信息估算的,可能与实际有偏差,可通过ANALYZE TABLE 表名更新统计信息。

10. Extra:额外信息(核心!)

含义:补充说明执行计划的关键细节,常见重要值如下:

含义优化指导
Using index使用覆盖索引(无需回表),性能极佳理想状态,尽量保留
Using where先扫描数据,再用 WHERE 过滤(可能索引失效)需检查是否能用索引过滤
Using index condition索引条件下推(ICP),先通过索引过滤部分数据,减少回表优化器自动优化,正常
Using filesort需额外排序(未使用索引排序),性能差必须优化(加排序字段索引)
Using temporary需创建临时表(如 GROUP BY/ORDER BY 字段无索引),性能极差必须优化(加联合索引)
Using join buffer多表连接时使用连接缓冲区(未用索引连接)需优化连接字段的索引
Impossible WHEREWHERE 条件永远为假(如WHERE 1=0),无数据返回检查 SQL 逻辑
Select tables optimized away聚合函数(如 COUNT (*))直接通过索引统计获取,无需扫描数据最优状态

三、EXPLAIN 实战案例(手把手分析)

案例 1:索引生效(理想情况)

-- 表结构:user(id PK, name 索引, age) EXPLAIN SELECT id, name FROM user WHERE name = '张三';

输出核心字段分析:

typekeyrowsExtra结论
refidx_name2Using index索引生效,覆盖索引无回表

分析

  • type=ref:使用非唯一索引匹配,索引生效;
  • key=idx_name:实际使用 name 索引;
  • Extra=Using index:覆盖索引,无需回表;
  • rows=2:仅扫描 2 行,性能优秀。

案例 2:索引失效(全表扫描)

EXPLAIN SELECT * FROM user WHERE DATE(create_time) = '2025-12-27';

输出核心字段分析:

typekeyrowsExtra结论
ALLNULL1000Using where索引失效,全表扫描

分析

  • type=ALL:全表扫描,索引失效;
  • key=NULL:未使用任何索引;
  • rows=1000:预估扫描 1000 行,性能差;
  • 原因:对索引字段create_time使用了DATE()函数,导致索引失效。

案例 3:联合索引部分生效

-- 联合索引:idx_a_b_c(a,b,c) EXPLAIN SELECT * FROM user WHERE a = 1 AND c = 3;

输出核心字段分析:

keykey_lenExtra结论
idx_a_b_c4Using where仅 a 字段的索引生效,c 失效

分析

  • key=idx_a_b_c:使用了联合索引,但key_len=4(仅 a 字段的长度);
  • 原因:破坏了最左前缀原则(跳过 b 直接用 c),导致 c 的索引失效;
  • 优化:调整查询条件为a=1 AND b IS NOT NULL AND c=3,或修改联合索引为idx_a_c

四、EXPLAIN 进阶用法

1. EXPLAIN EXTENDED(MySQL 5.6+)

  • 额外输出filtered字段(过滤百分比),表示经过 WHERE 过滤后剩余的行数比例;
  • 可通过SHOW WARNINGS查看优化器改写后的 SQL(比如隐式转换、条件简化):
    EXPLAIN EXTENDED SELECT * FROM user WHERE phone = 13800138000; SHOW WARNINGS; -- 会显示优化器将phone=13800138000改为phone=CAST(13800138000 AS CHAR)

2. EXPLAIN FORMAT=JSON(结构化输出)

  • 输出 JSON 格式的执行计划,包含更详细的成本计算(如cost_inforows_examined_per_scan);
  • 适合深度分析

3. 分析多表连接

多表连接时,EXPLAIN会返回多行(每张表一行),按id和执行顺序分析:

EXPLAIN SELECT * FROM user u JOIN `order` o ON u.id = o.user_id WHERE u.name = '张三';

重点关注:

  • 驱动表(先执行的表)的type是否为ref/const
  • 被驱动表的type是否为eq_ref(主键 / 唯一索引连接);
  • 避免type=ALL的表出现在连接的外层(会导致全表扫描后再连接)。

总结

  1. EXPLAIN 核心价值:无需执行 SQL,就能查看优化器的执行计划,定位索引失效、全表扫描、临时表 / 文件排序等性能问题;
  2. 核心关注字段type(访问类型,避免 ALL/index)、key(实际使用的索引,避免 NULL)、rows(预估扫描行数,越小越好)、Extra(是否有 Using filesort/Using temporary);
  3. 使用流程:写 SQL → EXPLAIN 分析 → 定位问题(如 type=ALL、key=NULL) → 优化(加索引 / 改 SQL) → 重新 EXPLAIN 验证。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/30 5:27:49

Open-AutoGLM移动端性能优化实录(延迟降低80%的秘密)

第一章:Open-AutoGLM移动端性能优化实录(延迟降低80%的秘密)在部署 Open-AutoGLM 到移动端时,初始版本的推理延迟高达 1200ms,严重影响用户体验。通过系统性分析与多轮优化,最终将端到端延迟降至 240ms&…

作者头像 李华
网站建设 2026/4/18 2:50:00

企业运营认知机器人工程化导向的规范性说明

目标:把“能持续运营的企业级智能体/认知机器人”从概念落到可采购、可建设、可验收、可治理的规范体系摘要企业运营认知机器人(COR)是一类以显式世界模型 认知闭环 可审计证据链为核心设计原则的企业级智能系统,能够在财务、供…

作者头像 李华
网站建设 2026/4/29 21:37:31

如何为你的游戏选择最佳图像缩放方案:OptiScaler深度体验指南

如何为你的游戏选择最佳图像缩放方案:OptiScaler深度体验指南 【免费下载链接】OptiScaler DLSS replacement for AMD/Intel/Nvidia cards with multiple upscalers (XeSS/FSR2/DLSS) 项目地址: https://gitcode.com/GitHub_Trending/op/OptiScaler 还在为游…

作者头像 李华
网站建设 2026/4/29 3:21:26

Bullseye系统下树莓派摄像头无法启动?核心要点解析

Bullseye系统下树莓派摄像头无法启动?一文讲透底层机制与实战修复你是不是也遇到过这种情况:硬件接好了,排线插到底了,旧系统跑得好好的摄像头,在升级到最新的Raspberry Pi OS Bullseye后突然“失明”——libcamera-he…

作者头像 李华
网站建设 2026/4/16 22:44:28

OpenCPN 航海导航软件终极指南:从新手到高手的完整教程

OpenCPN 航海导航软件终极指南:从新手到高手的完整教程 【免费下载链接】OpenCPN A concise ChartPlotter/Navigator. A cross-platform ship-borne GUI application supporting * GPS/GPDS Postition Input * BSB Raster Chart Display * S57 Vector ENChart Displ…

作者头像 李华
网站建设 2026/4/15 9:56:01

终极指南:如何用whisper-large-v3-turbo实现8倍速语音转文字

终极指南:如何用whisper-large-v3-turbo实现8倍速语音转文字 【免费下载链接】whisper-large-v3-turbo 项目地址: https://ai.gitcode.com/hf_mirrors/openai/whisper-large-v3-turbo 还在为漫长的语音转文字等待时间而焦虑吗?每次处理会议录音、…

作者头像 李华