优化SQL:如何使用 EXPLAIN

EXPLAIN是优化SQL查询不可或缺的工具。掌握其输出结果中 typeExtra列的含义,是定位性能问题的关键。通常的优化路径是:避免出现 ALL类型的全表扫描,并通过创建合适的索引来将查询类型提升到 refrange,同时留意 Extra列中是否有 Using temporaryUsing filesort等需要优化的提示。

下面这个表格汇总了使用 EXPLAIN时返回结果中各字段的核心含义。

字段 含义与解读要点
**id**​ SELECT 查询的序列号。id值越大,执行优先级越高;id相同,则从上往下执行
**select_type**​ 查询的类型,例如简单查询(SIMPLE)、主查询(PRIMARY)、子查询(SUBQUERY)、派生表查询(DERIVED)等。
**type**​ 访问类型 ,即MySQL决定如何查找表中的行。这是判断查询效率的关键指标,从优到劣常见的有:const/eq_ref> ref> range> index> ALL(全表扫描,需要优化)。
**possible_keys**​ 查询可能使用到的索引。
**key**​ 查询实际使用 到的索引。如果为 NULL,则表示未使用索引。
**key_len**​ 使用的索引字节数。可用于判断索引是否被完全利用。
**rows**​ MySQL 估算需要扫描的行数。通常数值越小越好。
**Extra**​ 包含查询执行的附加信息 。非常重要,常出现如 Using filesort(需要额外排序)、Using temporary(使用了临时表)等,都是需要关注的优化点。

如何使用 EXPLAIN

使用 EXPLAIN非常简单,只需在需要分析的 SQL 语句前加上 EXPLAIN关键字即可。从 MySQL 5.6.3 开始,它不仅可以分析 SELECT语句,还可以分析 DELETEINSERTREPLACEUPDATE语句。

复制代码
-- 基本用法
EXPLAIN SELECT * FROM your_table WHERE column_name = 'value';

-- 也可以使用 DESCRIBE 或 DESC,它们是 EXPLAIN 的同义词
DESCRIBE SELECT * FROM your_table;
DESC SELECT * FROM your_table;

在 MySQL 8.0 及更高版本中,还可以指定输出格式以获得更详尽或更直观的信息:

  • FORMAT=TRADITIONAL:默认格式,以表格形式展示。

  • FORMAT=JSON:提供非常详细的 JSON 格式信息,包含成本估算等更多数据。

  • FORMAT=TREE:MySQL 8.0.16 及以上版本可用,以树形结构展示执行过程,能清晰显示哈希连接等高级特性。

    -- 指定输出格式
    EXPLAIN FORMAT=JSON SELECT * FROM your_table;

此外,MySQL 8.0.18 引入了 EXPLAIN ANALYZE ,这是一个非常强大的功能。它不仅显示执行计划,还会实际执行该语句,并返回详细的执行时间、返回行数等实际运行数据,能更准确地评估性能。

复制代码
-- 使用 EXPLAIN ANALYZE 获取实际执行数据(MySQL 8.0.18+)
EXPLAIN ANALYZE SELECT * FROM your_table WHERE column_name = 'value';

重点字段详解与优化提示

  1. type 字段(核心性能指标)

    这是评估查询效率最重要的字段。应该致力于让查询的 type至少达到 range级别,最好能达到 ref

    • system/const:性能最佳。通常通过主键(PRIMARY KEY)或唯一索引(UNIQUE INDEX)进行等值查询时出现,表示只返回一行数据。

    • eq_ref:常见于多表关联查询,使用主键或唯一索引作为关联条件,对于前一张表的每一行,当前表只有一条记录与之匹配。

    • ref:使用普通索引进行查询,可能会返回多条匹配的记录。这是非常常见的、高效的索引使用方式。

    • range :使用了索引进行范围扫描(如 BETWEENIN><等)。

    • index:全索引扫描。虽然比全表扫描(ALL)好,因为它只遍历索引树,但如果索引很大,速度也可能较慢。

    • ALL全表扫描 。这意味着MySQL需要读取整个表来找到匹配的行。在数据量大的情况下,这是必须优化的信号。通常的解决方案是为查询条件创建合适的索引。

  2. Extra 字段(重要优化线索)

    这个字段提供了大量关于MySQL如何解析查询的额外信息。以下是一些需要特别注意的值:

    • Using index覆盖索引。表示查询的列都包含在索引中,无需回表读取数据行,性能非常好。

    • Using where:表示服务器在存储引擎检索行后进行了进一步的过滤。

    • Using temporary :表示MySQL为了执行查询创建了临时表 。这通常发生在排序(ORDER BY)和分组(GROUP BY)操作中,如果可能,应考虑通过索引来优化。

    • Using filesort :表示MySQL无法利用索引进行排序,需要额外的排序操作 。如果可能,应尝试为 ORDER BY子句创建合适的索引。

使用技巧与局限性

  • 结合 SHOW WARNINGS :在执行 EXPLAIN后,立即运行 SHOW WARNINGS;,可以查看优化器优化后的SQL语句,有时能提供更多线索。

  • 注意估算值EXPLAIN(不包括 ANALYZE)输出的 rows等字段是基于统计信息的估算值,并非精确值。

  • 局限性EXPLAIN不会考虑查询缓存的影响,也不能显示触发器、存储过程对查询的影响,并且它只解释查询过程,不执行查询(EXPLAIN ANALYZE除外)。

相关推荐
qq_589568101 小时前
springbootweb案例,出现访问 http://localhost:8080/list 一直处于浏览器运转阶段
java·网络协议·http·list·springboot
JAVA面经实录9171 小时前
计算机基础(完整版·超详细可背诵)
java·linux·数据结构·算法
晚风_END1 小时前
Linux|操作系统|最新版openzfs编译记录
linux·运维·服务器·数据库·spring·中间件·个人开发
AC赳赳老秦2 小时前
知识产权辅助:用 OpenClaw 批量生成专利交底书 / 软著申请材料,自动校验格式与内容合规性
java·人工智能·python·算法·elasticsearch·deepseek·openclaw
dLYG DUMS2 小时前
DBeaver连接本地MySQL、创建数据库表的基础操作
数据库·mysql
FYKJ_20102 小时前
springboot校园兼职平台--附源码02041
java·javascript·spring boot·python·eclipse·django·php
kumat3 小时前
分享-搭建个人系统 MySelfSys
sql·系统
苍煜3 小时前
MySQL分库分表和ES到底怎么选?
数据库·mysql·elasticsearch
茉莉玫瑰花茶3 小时前
Qt 信号与槽 [ 1 ]
开发语言·数据库·qt