当前位置:首页 > 技术 > 正文内容

MySQL EXPLAIN 结果解读

代码老兵 技术 22

MySQL 中,EXPLAIN 用来查看 SQL 查询执行计划,帮助你判断查询是否使用索引、扫描了多少行、连接方式如何等,是 SQL 性能优化最重要的工具之一。

基本用法:

EXPLAIN SELECT * FROM users WHERE id = 10;

返回一个表格,每一列都有特定含义。下面是常见字段的解读。


一、EXPLAIN 输出字段说明

典型结果:

idselect_typetabletypepossible_keyskeykey_lenrefrowsExtra

1 id

查询序号,表示执行顺序。

规则:

  • id 相同 → 按 从上到下顺序执行

  • id 不同 → id 越大越先执行

  • 子查询 id 会更大

示例:

id
3
2
1

执行顺序:

3 → 2 → 1

2 select_type

表示 查询类型

常见值:

类型含义
SIMPLE简单查询,没有子查询
PRIMARY外层查询
SUBQUERY子查询
DERIVEDFROM 子查询(派生表)
UNIONUNION 后的查询
UNION RESULTUNION 结果

示例:

SELECT * FROM users WHERE id IN (
 SELECT user_id FROM orders
);

子查询部分会显示:

SUBQUERY

3 table

当前访问的表

如果是子查询,可能显示:

<derived2>

表示临时派生表。


4 type

表示 访问类型 / 扫描方式,性能从好到差:

type含义
system表只有一行
const主键或唯一索引
eq_ref唯一索引连接
ref普通索引
range范围扫描
index全索引扫描
ALL全表扫描

性能排序:

system
const
eq_ref
ref
range
index
ALL

优化目标:

尽量避免:

ALL

因为是 全表扫描


5 possible_keys

可能使用的索引

例如:

possible_keys: idx_user_id, idx_email

说明:

MySQL 认为可以使用这些索引

不一定真的用


6 key

实际使用的索引

例如:

key: idx_user_id

如果:

key: NULL

说明 没有使用索引


7 key_len

使用的索引长度

用于判断:

  • 是否使用了 联合索引的全部字段

例如:

联合索引:

INDEX(a,b,c)

SQL:

WHERE a=1 AND b=2

key_len 只会显示 a+b 的长度


8 ref

表示 索引和哪个列比较

常见:

ref: const

表示:

WHERE id = 10

或者:

ref: users.id

表示 和另一个表字段比较


9 rows

MySQL 预估需要扫描的行数

例如:

rows: 10000

说明:

MySQL 估计需要扫描 1 万行数据

优化目标:

rows 越小越好

10 Extra

额外信息。

常见值:

Using where

表示:

需要再进行 WHERE 过滤

不是坏事。


Using index

表示:

覆盖索引(Covering Index)

SQL 只访问索引,不访问表。

性能非常好。


Using temporary

使用 临时表

常见于:

GROUP BY
ORDER BY

性能可能较差。


Using filesort

表示:

需要额外排序

MySQL 自己排序,而不是用索引。

例如:

ORDER BY create_time

如果 create_time 没索引,就会出现。


二、一个完整 EXPLAIN 示例

SQL:

EXPLAIN SELECT * FROM users WHERE email='a@test.com';

结果:

idselect_typetabletypekeyrowsExtra
1SIMPLEusersrefidx_email1Using where

解释:

  • type = ref → 使用普通索引

  • key = idx_email → 使用 email 索引

  • rows = 1 → 预计扫描 1 行

  • Using where → 还需要 WHERE 过滤

说明:

这个 SQL 性能很好

三、EXPLAIN 优化重点(实战经验)

重点关注 4 个字段:

type
key
rows
Extra

优化目标:

1 避免

type = ALL

说明:

全表扫描

2 rows 越小越好

例如:

rows = 1000000

说明扫描太多。


3 避免

Using filesort
Using temporary

4 尽量出现

Using index

说明:

覆盖索引

四、一个真实优化案例

原 SQL:

SELECT * FROM orders WHERE user_id=10;

EXPLAIN:

type: ALL
rows: 200000

说明:

没有索引

优化:

CREATE INDEX idx_user_id ON orders(user_id);

再次 EXPLAIN:

type: ref
rows: 5

性能提升 几百倍


五、MySQL 8 推荐使用 EXPLAIN ANALYZE

MySQL 8+

EXPLAIN ANALYZE SELECT ...

特点:

  • 显示 真实执行时间

  • 显示 真实扫描行数

比普通 EXPLAIN 更准确。


标签: MySQL

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。