优化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除外)。

相关推荐
行思理2 小时前
FastAdmin新手教程
java·开发语言·fastadmin
向上的车轮2 小时前
Apache Camel 与 Spring Integration的区别是什么?
java·spring·apache
Kiyra2 小时前
Spring Boot Starter 自定义开发:封装中间件配置
spring boot·redis·后端·缓存·中间件·性能优化·rocketmq
小于晏2 小时前
ThinkPHP中数据库索引优化指南:添加依据与实操要点
数据库·oracle
nsjqj2 小时前
JavaEE初阶:计算机是如何工作的
java·java-ee
URBBRGROUN4672 小时前
Spring AI Alibaba入门
java·人工智能·spring
Teable任意门互动2 小时前
从飞书多维表格 简道云到Teable多维表格:企业为何选择Teable作为新一代智能数据协作平台?
数据库·excel·钉钉·飞书·开源软件
她和夏天一样热2 小时前
【实战篇】设计模式在开发中的真实应用
java·开发语言·设计模式