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

相关推荐
一定要AK2 小时前
Spring 入门核心笔记
java·笔记·spring
A__tao2 小时前
Elasticsearch Mapping 一键生成 Java 实体类(支持嵌套 + 自动过滤注释)
java·python·elasticsearch
KevinCyao2 小时前
java视频短信接口怎么调用?SpringBoot集成视频短信及回调处理Demo
java·spring boot·音视频
科技小花2 小时前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸2 小时前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
凯尔萨厮2 小时前
创建SpringWeb项目(Spring2.0)
spring·mvc·mybatis
D4c-lovetrain2 小时前
linux个人心得22 (mysql)
数据库·mysql
迷藏4942 小时前
**发散创新:基于Rust实现的开源合规权限管理框架设计与实践**在现代软件架构中,**权限控制(RBAC)** 已成为保障
java·开发语言·python·rust·开源
總鑽風3 小时前
搭建Spring Boot + ELK日志平台,实现可视化日志监控
spring boot·elk·macos
阿里小阿希3 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql