MySQL——EXPLAIN用法详解

EXPLAIN是MySQL官方提供的sql分析的工具之一,可以用于模拟优化器执行sql查询语句,从而知道MySQL是如何处理sql语句。EXPLAIN主要用于分析查询语句或表结构的性能瓶颈。

以下是基于MySQL5.7.19版本进行分析的,不同版本之间略有差异。

1、EXPLAIN使用

explain+sql语句,通过执行explain可以获得sql语句执行的相关信息。

2、EXPLAIN包含的信息

MySQL EXPLAIN包含字段
列名说明
id执行编号,标识select所属的行。如果在语句中没子查询或关联查询,只有唯一的select,每行都将显示1。否则,内层的select语句一般会顺序编号,对应于其在原始语句中的位置
select_type显示本行是简单或复杂select。如果查询有任何复杂的子查询,则最外层标记为PRIMARY(DERIVED、UNION、UNION RESUlT)
table访问引用哪个表(引用某个查询,如“user”)
partitions匹配的分区
type数据访问/读取操作类型(ALL、index、range、ref、eq_ref、const/system、NULL)
possible_keys揭示哪一些索引可能有利于高效的查找
key显示mysql决定采用哪个索引来优化查询
key_len显示mysql在索引里使用的字节数
ref显示了之前的表在key列记录的索引中查找值所用的列或常量
rows为了找到所需的行而需要读取的行数,估算值,不精确。通过把所有rows列值相乘,可粗略估算整个查询会检查的行数
filtered表示此查询条件所过滤的数据的百分比
extra额外信息,如using index、filesort等

2.1 id

id是用来顺序标识整个查询中SELELCT语句的,在嵌套查询中id越大的语句越先执行。该值可能为NULL,如果这一行用来说明的是其他行的联合结果。大致分为下面几种情况:

(1)id相同,执行顺序由上至下

EXPLAIN select * from user,school,class where user.school_id = school.school_id and user.class_id = class.class_id

三个id都为1,表示具有相同的优先级,执行顺序由上而下,具体执行顺序由优化器决定,这里执行顺序为school,user,class。

(2)id不同,数字越大优先级越高

EXPLAIN select * from user where school_id = (select school_id from school where school_id = (select school_id from class where class_id = 2))

如果sql中存在子查询,那么id的序号会递增,id越大越先被执行。如上述查询,执行顺序是class、school、user,也就是说,最里面的子查询最先执行,由里往外执行。

如果上述查询中的“=”换成“in”,则运行结果会发生变化,原因是每执行一次最外层子查询,里面的子查询都会被重复执行,这也就是sql优化中提到的尽量不要使用in关键字

 使用in关键字示例:

EXPLAIN select * from user where school_id in (select school_id from school where school_id in (select school_id from class where class_id = 2))

2.2 select_type 

 select_type表示查询的类型

类型说明
simple简单子查询,不包含子查询和union
primary包含union或者子查询,最外层的部分标记为primary
subquery一般子查询中的子查询被标记为subquery,也就是位于select列表中的查询
derived派生表——该临时表是从子查询派生出来的,位于form中的子查询
union位于union中第二个及其以后的子查询被标记为union,第一个就被标记为primary如果是union位于from中则标记为derived
union result用来从匿名临时表里检索结果的select被标记为union result
EXPLAIN select * from user where school_id = (select school_id from school where school_id = (select school_id from class where class_id = 2))

2.3 table

table显示查询操作基于哪张表的。

EXPLAIN select user.* from user where school_id = (select school_id from school where school_id = 2)
union 
select user.* from user where class_id = (select class_id from class where class_id = 2)

table列并不一定是真实存在的表,比如上面出现<union1,3>,一般来说会出现下面的取值:

  • <union a,b>:输出结果中编号为 a 的行与编号为 b 的行的结果集的并集。
  • < derived a>:输出结果中编号为 a 的行的结果集,derived 表示这是一个派生结果集,如 FROM 子句中的查询。
  • < subquery a>:输出结果中编号为 a 的行的结果集,subquery 表示这是一个物化子查询。

2.4 partitions

partitions列是查询时匹配到的分区信息,对于非分区表值为NULL,当查询的是分区表时,partitions显示分区表命中的分区情况。

2.5 type

type显示的是访问类型,是较为重要的一个指标,性能从最好到最坏依次是 system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL。一般来说,得保证查询至少达到range级别,最好能达到ref。

类型说明
system这是const连接类型的一种特例,表仅有一行满足条件。
const当确定最多只会有一行匹配的时候,MySQL优化器会在查询前读取它而且只读取一次,因此非常快。当主键放入where子句时,mysql把这个查询转为一个常量(高效)
eq_ref最多只返回一条符合条件的记录。使用唯一性索引或主键查找时会发生 (高效)
ref一种索引访问,它返回所有匹配某个单个值的行。此类索引访问只有当使用非唯一性索引或唯一性索引非唯一性前缀时才会发生。这个类型跟eq_ref不同的是,它用在关联操作只使用了索引的最左前缀,或者索引不是UNIQUE和PRIMARY KEY。ref可以用于使用=或<=>操作符的带索引的列。
fulltext查询时使用 fulltext 索引。
ref_or_null对于某个字段既需要关联条件,也需要null 值的情况下。查询优化器会选择用ref_or_null 连接查询。
index_merge在查询过程中需要多个索引组合使用,通常出现在有or 关键字的sql 中。
unique_subquery该联接类型类似于index_subquery。子查询中的唯一索引。在某些in子查询里,用于替换eq_ref
index_subquery利用索引来关联子查询,不再全表扫描。用于非唯一索引,子查询可以返回重复值。类似于unique_subquery,但用于非唯一索引
range范围扫描,一个有限制的索引扫描。key 列显示使用了哪个索引。当使用=、 <>、>、>=、<、<=、IS NULL、<=>、BETWEEN 或者 IN 操作符,用常量比较关键字列时,可以使用 range
index和全表扫描一样。只是扫描表的时候按照索引次序进行而不是行。主要优点就是避免了排序, 但是开销仍然非常大。如在Extra列看到Using index,说明正在使用覆盖索引,只扫描索引的数据,它比按索引次序全表扫描的开销要小很多
all全表扫描,性能最差。

2.6 possible_keys

查询时可能使用的索引,一个或多个。查询涉及到的字段上若存在索引,则该索引将被列出。注意是可能,实际查询时不一定会用到。

2.7 key

查询时实际使用的索引,没有使用索引则为NULL。查询时若使用了覆盖索引,则该索引只出现在key字段中。

2.8 key_len

表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度。在不损失精确性的情况下,长度越短越好

key_len显示的值是索引字段可能的最大长度,并非实际使用长度,即key_len是根据表定义计算得到,不是通过表内检索。

key_len 字段能够帮你检查是否充分的利用上了索引。ken_len 越长,说明索引使用的越充分。

注意:key_len只计算where条件中用到的索引长度,而排序和分组即便是用到了索引,也不会计算到key_len中。

2.9 ref

显示索引的哪一列被使用了,常见的取值有:const, func,null,字段名。

  • 当使用常量等值查询,显示const
  • 当关联查询时,会显示相应关联表的关联字段
  • 如果查询条件使用了表达式函数,或者条件列发生内部隐式转换,可能显示为func
  • 其他情况null

2.10 rows

rows 列表示 MySQL 认为它执行查询时可能需要读取的行数,一般情况下这个值越小越好!

2.11 filtered

filtered 是一个百分比的值,表示符合条件的记录数的百分比。简单点说,这个字段表示存储引擎返回的数据在经过过滤后,剩下满足条件的记录数量的比例。

MySQL.5.7版本以前想要显示filtered需要使用explain extended命令。MySQL.5.7后,默认explain直接显示partitionsfiltered的信息。

2.12 Extra

Extra是EXPLAIN输出中另外一个很重要的列,该列显示MySQL在查询过程中的一些详细信息,MySQL查询优化器执行查询的过程中对查询计划的重要补充信息。

类型说明
Using filesortMySQL有两种方式可以生成有序的结果,通过排序操作或者使用索引,当Extra中出现了Using filesort 说明MySQL使用了后者,但注意虽然叫filesort但并不是说明就是用了文件来进行排序,只要可能排序都是在内存里完成的。大部分情况下利用索引排序更快,所以一般这时也要考虑优化查询了。使用文件完成排序操作,这是可能是ordery by,group by语句的结果,这可能是一个CPU密集型的过程,可以通过选择合适的索引来改进性能,用索引来为查询结果排序。
Using temporary用临时表保存中间结果,常用于GROUP BY 和 ORDER BY操作中,一般看到它说明查询需要优化了,就算避免不了临时表的使用也要尽量避免硬盘临时表的使用。
Not existsMYSQL优化了LEFT JOIN,一旦它找到了匹配LEFT JOIN标准的行, 就不再搜索了。
Using index说明查询是覆盖了索引的,不需要读取数据文件,从索引树(索引文件)中即可获得信息。如果同时出现using where,表明索引被用来执行索引键值的查找,没有using where,表明索引用来读取数据而非执行查找动作。这是MySQL服务层完成的,但无需再回表查询记录。
Using index condition这是MySQL 5.6出来的新特性,叫做“索引条件推送”。简单说一点就是MySQL原来在索引上是不能执行如like这样的操作的,但是现在可以了,这样减少了不必要的IO操作,但是只能用在二级索引上。
Using where使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给用户。注意:Extra列出现Using where表示MySQL服务器将存储引擎返回服务层以后再应用WHERE条件过滤。
Using join buffer使用了连接缓存:Block Nested Loop,连接算法是块嵌套循环连接;Batched Key Access,连接算法是批量索引连接
impossible wherewhere子句的值总是false,不能用来获取任何元组
select tables optimized away在没有GROUP BY子句的情况下,基于索引优化MIN/MAX操作,或者对于MyISAM存储引擎优化COUNT(*)操作,不必等到执行阶段再进行计算,查询执行计划生成的阶段即完成优化。
distinct优化distinct操作,在找到第一匹配的元组后即停止找同样值的动作

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/118525.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

筹备三年,自动驾驶L3标准将至,智驾产业链的关键一跃

‍作者|张祥威 编辑|德新 多位知情人士告诉HiEV&#xff0c;智能网联汽车准入试点通知&#xff0c;乐观预计将在一个月内发布。试点的推动&#xff0c;意味着国家层面的自动驾驶L3标准随之到来。 「L3标准内容大部分与主机厂相关&#xff0c;由工信部牵头&#xff0c;找了几家…

Redis3.2.12版本服务器迁移

1.新机器更新yum源 yum -y update 2.新机器安装redis数据库 yum install redis 3.新机器下载fedora的epel仓库 systemctl enable redis 4.将旧机器上的/etc/redis.conf拷贝到新机器的/config目录下 scp -r -P22 redis.config root162.32.196.57:/config/redis.config 5.新机器启…

4、让电机转起来【51单片机控制步进电机-TB6600系列】

摘要&#xff1a;本节介绍用简单的方式&#xff0c;让步进电机转起来。其目的之一是对电机转动有直观的感受&#xff0c;二是熟悉整个开发流程。 本系列教程必要的51单片机基础包括IO口操作、中断、定时器三个部分&#xff0c;相关基础教程网上很多&#xff0c;可以自行学习 一…

王道p149 3.编写后序遍历二叉树的非递归算法(c语言代码实现)

本题代码如下 void postorder(tree* t) {struct treenode* stack[100];//初始化结构体数组int top -1;//让栈顶指向-1treenode* p *t;while (p || top ! -1)//p不为空&#xff0c;并且栈不为空{if (p){top;//p不为空&#xff0c;将p压入栈中stack[top] p;p p->lchild;/…

Kafka-Java一:Spring实现kafka消息的简单发送

目录 写在前面 一、创建maven项目 二、引入依赖 2.1、maven项目创建完成后&#xff0c;需要引入以下依赖 2.2、创建工程目录 三、创建生产者 3.1、创建生产者&#xff0c;同步发送消息 3.2、创建生产者&#xff0c;异步发送消息 四、同步发送消息和异步发送消息的区别…

FLStudio21汉化破解激活版下载,Fl Studio 2024中文破解版激活补丁

最新版本FL Studio 21官方中文汉化激破解版是比利时Image-Line公司开发的DAW。在去年DTM站的DAW调查中&#xff0c;在世界上很受欢迎&#xff0c;特别是作为EDM制作工具被广泛使用。从1997年以FruityLoops的名字发行的时候开始&#xff0c;FL Studio 21就一直作为Windows专用的…

Whisper 整体架构图

Attention 注意力机制模块&#xff0c;兼容自注意力和交叉注意力。 AttentionBlock Transformer 模块&#xff0c;包含一个自注意力&#xff0c;一个交叉注意力&#xff08;可选&#xff09;和一个 MLP 模块。 AudioEncoderTextDecoder 音频编码器和文本解码器。编码器的 Tr…

python 桌面软件开发-matplotlib画图鼠标缩放拖动

继上一篇在 Java 中缩放拖动图片后&#xff0c;在python matplotlib中也来实现一个自由缩放拖动的例子&#xff1a; python matplotlib 中缩放&#xff0c;较为简单&#xff0c;只需要通过设置要显示的 x y坐标的显示范围即可。基于此&#xff0c;实现一个鼠标监听回调&#xf…

Docker镜像仓库

Docker镜像仓库 一、Docker镜像的创建1.1、基于已有镜像创建1.2、基于本地模板创建1.3、基于Dockerfile创建&#xff08;使用最广泛&#xff09;1.3.1、联合文件系统&#xff08;UnionFS&#xff09;1.3.2、镜像加载原理1.3.3、Dockerfile1.3.4、Docker 镜像结构的分层 二、如何…

【带头学C++】----- 1.基础知识 ---- 1.21.23.9 位运算符的综合应用

最近做任务&#xff0c;公司项目比较重&#xff0c;赶上1024的活动流量券任务&#xff0c;内容治疗略微有一些杂乱&#xff0c;后期会把专栏目录重新搞一下&#xff0c;内容我是融合了很多课程和书籍包含ai的一些理解&#xff0c;我整理和增加了自己的见解和代码贴图&#xff0…

newstar week3 pwn

newstar week3 pwn 巩固知识&#xff0c;如有错误记得纠正&#xff0c;感谢师傅们的评阅 puts or system? Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: No PIE (0x400000)int __cdecl main(int argc, const…

uni-app:解决异步请求返回值问题

可以使用 Promise 或者回调函数来处理异步请求的返回值。 方法一&#xff1a; Promise处理异步请求的返回值 使用 Promise 可以将异步请求的结果通过 resolve 和 reject 返回&#xff0c;然后通过 .then() 方法获取成功的结果&#xff0c;通过 .catch() 方法获取错误信息。 …

鸿鹄工程项目管理系统 Spring Cloud+Spring Boot+Mybatis+Vue+ElementUI+前后端分离构建工程项目管理系统项目背景

鸿鹄工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离构建工程项目管理系统 1. 项目背景 一、随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性&#xff0c;公司对内部工程管…

统计文本词频的几种方法(Python)

目录 1. 单句的词频统计 2. 文章的词频统计 方法一&#xff1a;运用集合去重方法 方法二&#xff1a;运用字典统计 方法三&#xff1a;使用计数器 词频统计是自然语言处理的基本任务&#xff0c;针对一段句子、一篇文章或一组文章&#xff0c;统计文章中每个单词出现的次数…

40.查找练习题(王道2023数据结构第7章)

试题1&#xff08;王道7.2.4节综合练习5&#xff09;&#xff1a; 写出折半查找的递归算法。 #include<stdio.h> #include<stdlib.h> #include<string.h>#define MAXSIZE 10 #define ElemType int #define Status inttypedef struct{int data[MAXSIZE]; /…

GD32_定时器输入捕获波形频率

GD32_定时器输入捕获波形频率&#xff08;多通道轮询&#xff09; 之前项目上用到一个使用定时器捕获输入采集风扇波形频率得到风扇转速的模块&#xff0c;作为笔记简单记录以下当时的逻辑结构和遇到的问题&#xff0c;有需要参考源码、有疑问或需要提供帮助的可以留言告知 。…

Spring Event

前言 ApplicationEvent 与 ApplicationListener 应用 实现 基于注解 事件过滤 异步事件监听 好处及应用场景 源码阅读 总结 1前言 ApplicationContext 中的事件处理是通过 ApplicationEvent 类和 ApplicationListener 接口提供的。如果将实现了 ApplicationListener …

【AI视野·今日Robot 机器人论文速览 第五十八期】Thu, 19 Oct 2023

AI视野今日CS.Robotics 机器人学论文速览 Thu, 19 Oct 2023 Totally 25 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Robotics Papers InViG: Benchmarking Interactive Visual Grounding with 500K Human-Robot Interactions Authors Hanbo Zhang, Jie Xu, Yuch…

Qt生成PDF报告

文章目录 一、示意图二、实现部分代码总结 一、示意图 二、实现部分代码 //! 生成测试报告 void MainWindow::createPdf(QString filename, _pdf_msg_& msg, const QMap<QString, int>& ok, const QMap<QString, int>& err) {//QDir dir;if(!dir.exis…