听说你对explain 很懂?

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介: explain所有人都应该很熟悉,通过它我们可以知道SQL是如何执行的,虽然不是100%管用,但是至少大多数场景通过explain的输出结果我们能直观的看到执行计划的相关信息。

explain所有人都应该很熟悉,通过它我们可以知道SQL是如何执行的,虽然不是100%管用,但是至少大多数场景通过explain的输出结果我们能直观的看到执行计划的相关信息。

早一些的版本explain还只能查看select语句,现在已经能支持deleteupdateinsertreplace了。

刚开始我想写这个的时候只是因为这个东西经常性不用就忘记,写了发现其实这个东西真的挺麻烦的,要把每个场景都整出来麻烦的很。

id

查询编号,如果没有子查询或者联合查询的话,就只有一条,如果是联合查询的话,那么会出现一条id为null的记录,并且标志查询结果,因为union结果会放到临时表中,所以我们看到这里的表名是<union1,2>这种格式。

079a2a7cd93cfaad61b9fab96a5b5cf7.jpg

select_type

关联类型,决定访问表的方式。

9c86883437246b722e7fb7c49960edab.jpg

SIMPLE

简单查询,代表没有子查询或者union

PRIMARY

如果不是简单查询,那么最外层查询就会被标记成PRIMARY。

UNION&UNION RESULT

从上图可以看出来了,包含联合查询,第一个被标记成了PRIMARY,union之后的查询被标记成UNION,以及最后产生的UNION RESULT

DERIVED

用来标记出现在from里的子查询,这个结果会放入临时表中,也叫做派生表。

3b5e772df756f6b5f1c478327010f4b0.jpg

这个对于低版本的Mysql可能显示是这样的,高一点可能你看到的还是PRIMARY,因为被Mysql优化了。我换一个版本的Mysql和SQL执行可以验证到这个结果。

d639217fa3da60cbd43666ba33ac156f.jpg

SUBQUERY

不在from里的子查询。

d02c2971acc8b93f901de6fcb26583ce.jpg

DEPENDENT

代表关联子查询(子查询使用了外部查询包含的列),和UNIONSUBQUERY组合产生不同的结果。

9782879eaa2b58a918b705570acb2221.jpg

UNCACHEABLE

代表不能缓存的子查询,也可以和UNIONSUBQUERY组合产生不同的结果。

ed0907ca5ea9393630f9ed7c06843c08.jpg

MATERIALIZED

物化子查询是Mysql对子查询的优化,第一次执行子查询时会将结果保存到临时表,物化子查询只需要执行一次。

比如上述DERIVED就是物化的一种体现,与之对应的就是DEPENDENT,每次子查询都需要重新调用。

这个结果无法直观的看出来,可以用FORMAT=JSON命令查看materialized_from_subquery字段。

2300d13eee61aac36d99edde79700f5e.jpg

table

显示表名,从上述的一些图中可以观察到UNION_RESULT和DERIVED显示的表名都有一些自己的命名规则。

比如UNION_RESULT产生的是<unionM,N>,DERIVED产生的是。

partitions

数据的分区信息,没有分区忽略就好了。

type

关联类型,决定通过什么方式找到每一行数据。以下按照速度由快到慢。

system>const>eq_ref>ref>fulltext>ref_or_null>index_merge>unique_subquery>index_subquery>range>index>ALL。

864bfb1d597e770102c89594916bdd8f.jpg

system&const

这通常是最快的查找方式,代表Mysql通过优化最终转换成常量查询,最常规的做法就是直接通过主键或者唯一索引查询。

7b2e4070e7f2ba9352b5ca9711d25a65.jpg

而system是const的一个特例(只有一行数据的系统表),随便找一张系统表,就插入一条数据就可以看到system了。

fdbe20341dc25bd70294375020ab5670.jpg

eq_ref

通常通过主键索引或者唯一索引查询时会看到eq_ref,它最多只返回一条数据。user_id是唯一索引,为了测试就关联以下主键索引。

18818feb08c27bbfcb5db6ebe3f1c76b.jpg

ref

也是通过索引查找,但是和eq_ref不同,ref可能匹配到多条符合条件的数据,比如最左前缀匹配或者不是主键和唯一索引。

最简单的办法,随便查一个普通索引就可以看到。

b957c251e278862cfa81e6ad9fb022c1.jpg

fulltext

使用FULLTEXT索引

ref_or_null

和ref类似,但是还要进行一次查询找到NULL的数据。

这相当于是对于IS NULL查询的优化,如果表数据量太少的话,你或许能看到这里类型是全表扫描。

bc5f6875d75c9f2ff702f1d043786bfa.jpg

index_merge

索引合并是在Mysql5.1之后引入的,就像下面的一个OR查询,按照原来的想法要么用name的索引,要么就是用age的索引,有了索引合并就不一样了。

对于这种单表查询(无法跨表合并)用到了多个索引的情况,每个索引都可能返回一个结果,Mysql会对结果进行取并集、交集,这就是索引合并了。

6b17aed6d31120b89ffce147c1d6c5ba.jpg

unique_subquery

按照官方文档所说,unique_subquery只是eq_ref的一个特例,对于下图中这种in的语句查询会出现以提高查询效率。

由于Mysql会对select进行优化,基本无法出现这个场景,只能用update这种语句了。

5dc0c5c3fa2a703171e05d6f663376c1.jpg

range

看名字就知道,范围查询,其实就是带有限制条件的索引扫描。

常见的范围查询比如between and,>,<,like,in 都有可能出现range。

a71b6ef118e9aa61addd8dcb8beba9c2.jpg

index

跟全表扫描类似,只是扫表是按照索引顺序进行。

ALL

全表扫描,没啥好说的。

possible_keys

可以使用哪些索引。

key

实际决定使用哪个索引。

key_len

索引字段的可能最大长度,不是表中实际数据使用的长度。

ref

表示key展示的索引实际使用的列或者常量。

rows

查询数据需要读取的行数,只是一个预估的数值,但是能很直观的看出SQL的优劣了。

filtered

5.1版本之后新增字段,表示针对符合查询条件的记录数的百分比估算,用rows和filtered相乘可以计算出关联表的行数。

Extra

解析查询的附加额外信息,这个太多了,有兴趣可以自己看官方文档,只列举一些常见的。

Using index

使用覆盖索引。

Using index condition

可以使用索引下推(不一定真的使用了),索引下推简单来说就是加上了条件筛选,减少了回表的操作。

d08134705c5cfe5c6c6d9c9e3c3a151d.jpg

Using temporary

排序使用了临时表。

Using filesort

使用外部索引文件排序,但是不能从这里看出是内存还是磁盘排序,我们只能知道更消耗性能。

Using where

where过滤,没啥好说的。

Zero limit

除非你写个LIMIT 0。

Using sort_union(), Using union(), sing intersect()

使用了索引合并,参看上文。

总结

7cf5f12814fb672a57aa682a1dda5a43.jpg

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
网络协议 Unix Linux
OpenOCD(五):调试适配器配置
OpenOCD(五):调试适配器配置
1145 0
|
6月前
|
Ubuntu 网络协议 应用服务中间件
在 Ubuntu 上安装 Nginx
在 Ubuntu 上安装和配置 Nginx 非常简单。首先更新系统包,然后通过 `apt` 安装 Nginx,检查服务状态并配置防火墙规则。访问服务器 IP 测试是否成功显示默认页面。还可管理服务、创建虚拟主机及排查常见问题,适合新手快速上手部署高性能 Web 服务。
777 0
|
API
[已解决]openai.error.APIConnectionError: Error communicating with OpenAI: HTTPSConnectionPool(host=‘api
[已解决]openai.error.APIConnectionError: Error communicating with OpenAI: HTTPSConnectionPool(host=‘api
2610 0
|
关系型数据库 MySQL Java
实时计算 Flink版操作报错之遇到java.lang.IllegalStateException: The elasticsearch emitter must be serializable.的错误,如何处理
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
|
机器学习/深度学习 人工智能 自然语言处理
软件测试中的人工智能:改变游戏规则的革新
在这篇技术性文章中,我们将深入探讨人工智能(AI)如何彻底改变了软件测试领域。从自动化测试到智能缺陷检测,AI不仅提高了测试的效率和准确性,还为软件开发团队提供了前所未有的洞察力。通过具体案例,本文揭示了AI在软件测试中应用的现状、挑战及未来趋势,强调了技术创新在提升软件质量与开发效率中的关键作用。
|
机器学习/深度学习 编解码 文件存储
深度学习中的模型压缩技术:从理论到实践
本文旨在探讨深度学习领域中的模型压缩技术,包括其背后的理论基础、常见方法以及在实际场景中的应用。我们将从基本的量化和剪枝技术开始,逐步深入到更高级的知识蒸馏和模型架构搜索。通过具体案例分析,本文将展示这些技术如何有效减少模型的大小与计算量,同时保持甚至提升模型的性能。最后,我们将讨论模型压缩技术未来的发展方向及其潜在影响。
|
前端开发 Java 数据库
springBoot:template engine&自定义一个mvc&后端给前端传数据&增删改查 (三)
本文介绍了如何自定义一个 MVC 框架,包括后端向前端传递数据、前后端代理配置、实现增删改查功能以及分页查询。详细展示了代码示例,从配置文件到控制器、服务层和数据访问层的实现,帮助开发者快速理解和应用。
172 0
|
关系型数据库 MySQL 数据库
MySQL避免索引失效
MySQL避免索引失效
|
存储
THREEJS实战6_加载fbx模型
THREEJS实战6_加载fbx模型
1242 1
|
存储 资源调度 JavaScript
package.json——从vue的package.json来详细说明package.json内容
package.json——从vue的package.json来详细说明package.json内容
380 0