【SQL优化】不再抓瞎!手把手教你读懂MySQL Explain执行计划

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: 本文详解MySQL执行计划工具EXPLAIN,教你读懂其输出的“天书”表格。重点掌握四个核心指标:`type`(访问类型)、`key`(实际使用索引)、`Extra`(额外信息)和`rows`(扫描行数)。通过实战案例解析慢查询成因与优化方案,助你快速定位SQL性能瓶颈,写出高效数据库查询。

前言

写 SQL 很容易,写出高性能的 SQL 却很难。

当你发现接口响应慢了,第一反应肯定是:“这个 SQL 到底走了索引没?”

别去猜,MySQL 提供了最强大的诊断工具 —— EXPLAIN 命令。

它能模拟优化器执行 SQL 查询语句,从而知道 MySQL 是如何处理你的 SQL 的。

今天我们就来破解 EXPLAIN 输出的那张“天书”表格,重点掌握 3 个最核心的指标

1. 怎么用?

用法超级简单,就在你的 SELECT 语句前面加上 EXPLAIN 即可。

SQL

EXPLAIN SELECT * FROM user WHERE id = 1;

执行后,你会看到类似下面的一张表:

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE user const PRIMARY PRIMARY 4 const 1 NULL

这就是执行计划。接下来我们逐一拆解重点。


2. 核心指标一:type (访问类型) —— 性能的风向标

这是最重要的一列!它告诉我们 MySQL 是怎么查找数据的:是根据索引直接定位,还是苦逼地全表扫描?

性能从好到坏依次是:

  1. system / const (最快)
  • 含义: 只有一行匹配。
  • 场景: 根据 主键唯一索引 查询。
  • 例子: WHERE id = 1
  1. eq_ref
  • 含义: 使用主键或唯一索引进行的关联查询。
  • 场景: 多表连接时,连接条件是主键。
  1. ref (常见/合格)
  • 含义: 使用了普通索引(非唯一)。
  • 场景: WHERE name = 'Tom' (name 字段有索引)。
  1. range (必须达到)
  • 含义: 索引范围扫描。
  • 场景: BETWEEN, >, <, IN 等查询。
  • 例子: WHERE age > 18
  1. index (较差)
  • 含义: 全索引扫描。虽然没扫描数据行,但把整个索引树扫了一遍。
  • 场景: SELECT id FROM user (id是索引,但没加条件)。
  1. ALL (最差/必须优化)
  • 含义: 全表扫描 (Full Table Scan)
  • 场景: 没建索引,或者索引失效(如 LIKE '%张')。
  • 后果: 如果表有百万数据,这波操作就是灾难。

优化目标: 至少要达到 range 级别,最好能达到 ref


3. 核心指标二:key (实际使用的索引)

这一列告诉你真相:MySQL 到底有没有用你建的索引?

  • possible_keys:显示可能应用在这张表上的索引(理论值)。
  • key:实际使用的索引(实际值)。
  • 如果为 NULL,说明没走索引,快去检查 WHERE 条件!
  • 如果 possible_keys 有值但 key 为 NULL,说明 MySQL 觉得走索引比全表扫描还慢(通常发生在数据量很小,或者数据分布极不均匀时)。

4. 核心指标三:Extra (额外信息) —— 藏着魔鬼的细节

这一列包含了很多额外信息,注意看有没有出现以下**“红色警报”**:

  1. Using filesort (严重)
  • 含义: MySQL 无法利用索引完成排序,必须在内存或磁盘中进行额外的排序操作。
  • 后果: CPU 消耗巨大。
  • 解决:ORDER BY 的字段加上索引。
  1. Using temporary (严重)
  • 含义: 使用了临时表来保存中间结果。
  • 场景: 常见于 GROUP BYDISTINCT
  • 解决: 优化索引,避免创建临时表。
  1. Using index (好事)
  • 含义: 覆盖索引 (Covering Index)
  • 解释: 查询的列全都在索引树里就能找到,不需要回表去查数据行。这是查询性能的最高境界

5. 核心指标四:rows (扫描行数)

  • 含义: MySQL 预估为了找到你想要的数据,需要扫描多少行。
  • 解读: 这个数字越小越好。
  • 如果你查 1 条数据,rows 却是 10000,说明索引建立得很糟糕,或者区分度太低。

实战案例:读懂一个慢查询

假设 SQL 是:

SQL

SELECT * FROM order WHERE user_id = 100 ORDER BY create_time;

EXPLAIN 结果 A(优化前):

  • type: ALL
  • key: NULL
  • Extra: Using filesort
  • 分析: 全表扫描 + 文件排序,双重打击,必须死。

优化方案: 建立联合索引 idx_user_time (user_id, create_time)

EXPLAIN 结果 B(优化后):

  • type: ref (根据 user_id 查找)
  • key: idx_user_time
  • Extra: NULL (利用索引原本的顺序,避免了 filesort)
  • 分析: 完美!

总结

以后看 EXPLAIN,先看这三点:

  1. type 是不是 ALL?(是就得改)
  2. key 是不是 NULL?(是就加索引)
  3. Extra 有没有 filesort / temporary?(有就优化索引顺序)
相关文章
|
3天前
|
Java Linux 开发工具
Linux
本文介绍如何将一个简单的SpringBoot应用打包并部署到Linux服务器。包括项目搭建、JAR包打包、JDK安装配置、应用上传与启动,以及通过心跳接口验证服务是否正常运行的完整流程,适用于Java应用的Linux部署入门学习。
|
6月前
|
数据安全/隐私保护
贴吧自动发帖工具, 贴吧自动评论脚本,顶贴回复发帖插件
这个代码实现了贴吧自动发帖、自动回复、获取帖子列表等功能。主要使用了requests库进行网络请求
|
3天前
|
监控 Java Sentinel
Sentinel安装与集成
介绍如何切换hmall-micro项目至dev_02分支并提交代码,强调多分支并行开发模式。随后讲解Sentinel服务保护框架的安装与配置,包括控制台部署、本地运行及项目集成,实现微服务熔断降级,并通过簇点链路监控接口。
Sentinel安装与集成
|
3天前
|
人工智能 Java 微服务
微服务保护方案
Spring Cloud微服务中,服务保护机制对保障系统稳定性至关重要,主要包括熔断、降级、超时、线程隔离和限流。熔断快速失败避免雪崩,降级提供默认响应保证核心功能,超时防止长时间等待,线程隔离限制故障影响范围,限流控制流量峰值,共同提升系统容错与可用性。
微服务保护方案
|
3天前
|
Java Sentinel 微服务
实现降级
本文介绍如何在Spring Cloud微服务中通过Sentinel实现Feign接口的降级处理。重点采用`FallbackFactory`方式,在调用方(如cart-service)为`ItemClient`接口编写降级逻辑,捕获远程调用异常并返回兜底数据。需配置Feign启用Sentinel,定义降级类实现`FallbackFactory`接口,并在`@FeignClient`中指定`fallbackFactory`。最终通过停止item-service进行测试,验证购物车页面在商品信息获取失败时仍可降级展示,保障系统稳定性。适用于服务熔断与容错场景。
实现降级
|
3天前
|
缓存 前端开发 安全
数据同步原理
Soul网关通过推拉模式实现配置数据同步,支持WebSocket、HTTP长轮询和Zookeeper三种策略。管理员在后台变更配置后,事件被发布并根据同步策略推送到网关,实现秒级更新。HTTP长轮询借鉴Apollo与Nacos设计,结合异步Servlet机制,确保准实时且高效。
数据同步原理
|
3天前
|
存储 算法 BI
xxljob本地运行
本文介绍XXL-JOB分布式任务调度框架的部署与使用,涵盖源码获取、服务端数据库配置、客户端注册及任务调度配置,支持多种路由策略与分片广播,助力高效实现定时任务管理。
 xxljob本地运行
|
3天前
|
存储 安全 Java
认证源码分析与自定义后端认证逻辑
本文深入分析Spring Security认证流程,从UsernamePasswordAuthenticationFilter切入,详解AuthenticationManager、ProviderManager及AbstractUserDetailsAuthenticationProvider的认证机制,最终实现自定义UserDetailsService,完成基于数据库的用户认证逻辑。
 认证源码分析与自定义后端认证逻辑
|
3天前
|
运维 监控 Java
【Linux基础】开发日常:盘点后端开发中最高频使用的10个Linux命令
本文为后端开发者整理了日常运维中最常用的10个Linux命令,涵盖文件查看、日志监控、进程管理、网络排查等核心场景。从`ls`、`cd`到`tail`、`grep`,再到`ps`、`netstat`、`top`等,结合实际案例讲解高频用法,助你高效应对服务器操作,提升开发效率。
|
3天前
|
Java Shell 开发工具
【Git入门】Git常用命令大全:从add到push,一图胜千言
本文深入浅出地讲解Git核心概念与常用命令,涵盖工作区、暂存区、本地仓库和远程仓库三大区域,梳理从配置、克隆、提交到同步的完整流程,并介绍撤销修改、查看历史、.gitignore等实用技巧,助力开发者高效协作。