MySQL的执行计划详解(Explain)(整合版)

目录
  • MySQL的执行计划详解(Explain)(整合版)
    • 1、MySQL执行计划的定义
    • 2、Explain分析示例
    • 3、语法展示
    • 4、explain中的列
        • 4.1、id
        • 4.2、select_type
        • 4.3、table
        • 4.4、type(重要的)
        • 4.5、possible_keys
        • 4.6、key
        • 4.7、key_len
        • 4.8、ref
        • 4.9、rows
        • 4.10、fitered
        • 4.11、Extra

MySQL的执行计划详解(Explain)(整合版)

1、MySQL执行计划的定义

在 MySQL 中可以通过 explain 关键字模拟优化器执行 SQL语句,从而知道 MySQL 是如何处理 SQL 语句的。

2、Explain分析示例

CREATE TABLE `actor` (`id` int(11) NOT NULL,`name` varchar(45) DEFAULT NULL,`update_time` datetime DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;CREATE TABLE `film` (`id` int(11) NOT NULL,`name` varchar(10) DEFAULT NULL,PRIMARY KEY (`id`),KEY `idx_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;CREATE TABLE `film_actor` (`id` int(11) NOT NULL,`film_id` int(11) NOT NULL,`actor_id` int(11) NOT NULL,`remark` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`),KEY `idx_film_actor_id` (`film_id`,`actor_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

3、语法展示

EXPLAIN select * from actor;

img

EXPLAIN EXTENDED select * from actor where id=1;
show WARNINGS;

img

4、explain中的列

4.1、id

查询执行顺序:
id 值相同时表示从上向下执行
id 值相同被视为一组
如果是子查询,id 值会递增,id 值越高,优先级越高
id为NULL最后执行。

4.2、select_type

simple:表示查询中不包含子查询或者 union

EXPLAIN select * from actor where id=1;

img

primary:当查询中包含任何复杂的子部分,最外层的查询被标记成 primary
derived:在 from 的列表中包含的子查询被标记成 derived
subquery:在 select 或 where 列表中包含了子查询,则子查询被标记成 subquery

用个例子来了解primary、subquery和derived

set session optimizer_switch='derived_merge=off';#关闭mysql5.7新特性对衍生表的合并优化explain select (select 1 from actor where id = 1) from (select * from film where id = 1) der;
#der是衍生表set session optimizer_switch='derived_merge=on'; #还原默认配置

img

union:两个 select 查询时前一个标记为 PRIMARY,后一个标记为 UNION。

union 出现在 from 从句子查询中,外层 select 标记为 PIRMARY,union 中第一个查询为 DERIVED,第二个子查询标记为 UNION

explain select 1 union all select 1;

img

unionresult:从 union 表获取结果的 select 被标记成 union result 。

4.3、table

显示这一行的数据是关于哪张表的。
当 from 子句中有子查询时,table列是 格式,表示当前查询依赖 id=N 的查询,于是先执行 id=N 的查询。
当有 union 时,UNION RESULT 的 table 列的值为<union1,2>,1和2表示参与 union 的 select 行id。

4.4、type(重要的)

这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为 system > const > eq_reg > ref > range > index > ALL。
一般来说,得保证查询达到range级别,最好达到ref

NULL:mysql能够在优化阶段分解查询语句,在执行阶段用不着再访问表或索引。例如:在索引列中选取最小值,可以单独查找索引来完成,不需要在执行时访问表

explain select min(id) from film;

system:表中只有一行数据。属于 const 的特例。如果物理表中就一行数据为 ALL
const :查询结果最多有一个匹配行。因为只有一行,所以可以被视为常量。const 查询速度非常快,因为只读一次。一般情况下把主键或唯一索引作为唯一条件的查询都是 const

set session optimizer_switch='derived_merge=off'
explain select * from (select * from film where id = 1) tmp;
set session optimizer_switch='derived_merge=on'

[!TIP]

诺出现报错,将第一行set session optimizer_switch='derived_merge=off'注释

eq_ref:查询时查询外键表全部数据。且只能查询主键列或关联列。且外键表中外键列中数据不能有重复数据,且这些数据都必须在主键表中有对应数据(主键表中数据可以有没有用到的)

img

explain select * from film_actor left join film on film_actor.film_id = film.id

ref:比 eq_ref,不使用唯一索引,而是使用普通索引或者唯一性索引的部分前缀,索引要和某个值相比较,可能会找到多个符合条件的行。
简单 select 查询,name是普通索引(非唯一索引)

explain select * from film where name = 'film1';

img

关联表查询,idx_film_actor_id是film_id和actor_id的联合索引,这里使用到了film_actor的左边前缀film_id部分

explain select film_id from film left join film_actor on film.id = film_actor.film_id;

ig

[!TIP]

LEFT JOIN(也称为左连接),确保了左表(film)的所有记录都被包含在结果集中,即使它们在右表(film_actor)中没有匹配的记录。

range:把这个列当作条件只检索其中一个范围。常见 where 从句中出现 between、<、>、>=、in 等。主要应用在具有索引的列中

explain select * from actor where id > 1;

img

index:扫描全索引就能拿到结果,一般是扫描某个二级索引,这种扫描不会从索引树根节点开始快速查找,而是直接对二级索引的叶子节点遍历和扫描,速度还是比较慢的,这种查询一般为使用覆盖索引,二级索引一般比较小,所以这种通常比ALL快一些

explain select * from film;

img

ALL:即全表扫描,扫描你的聚簇索引的所有叶子节点。通常情况下这需要增加索引来进行优化了。

explain select * from actor;

img

4.5、possible_keys

查询条件字段涉及到的索引,可能没有使用。
explain 时可能出现 possible_keys 有列,而 key 显示 NULL 的情况,这种情况是因为表中数据不多,mysql认为索引对此查询帮助不大,选择了全表查询。
如果该列是NULL,则没有相关的索引。在这种情况下,可以通过检查 where 子句看是否可以创造一个适当的索引来提高查询性能,然后用 explain 查看效果

4.6、key

实际使用的索引。如果为 NULL,则没有使用索引。
如果想强制mysql使用或忽视possible_keys列中的索引,在查询中使用 forceindex、ignore index。

4.7、key_len

表示索引中使用的字节数,查询中使用的索引的长度(最大可能长度),并非实际使用长度,理论上长度越短越好。key_len 是根据表定义计算而得的,不是通过表内检索出的。
举个例子来说:
film_actor的联合索引 idx_film_actor_id 由 film_id 和 actor_id 两个int列组成,并且每个int是4字节。通过结果中的key_len=4可推断出查询使用了第一个列:film_id列来执行索引查找。

explain select * from film_actor where film_id = 2;

img

iimg

4.8、ref

显示索引的哪一列被使用了,如果可能的话,是一个常量 const。

4.9、rows

根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数。注意这个不是结果集里的行数。

4.10、fitered

显示了通过条件过滤出的行数的百分比估计值。

4.11、Extra

MYSQL 如何解析查询的额外信息。

  1. Distinct:MySQL 发现第 1 个匹配行后,停止为当前的行组合搜索更多的行。

  2. Not exists:MySQL 能够对查询进行 LEFT JOIN 优化,发现 1 个匹配 LEFT JOIN 标准的行后,不再为前面的的行组合在该表内检查更多的行。

  3. range checked for each record (index map: #):MySQL 没有发现好的可以使用的索引,但发现如果来自前面的表的列值已知,可能部分索引可以使用。

  4. Using filesort:MySQL 需要额外的一次传递,以找出如何按排序顺序检索行。将用外部排序而不是索引排序,数据较小时从内存排序,否则需要在磁盘完成排序。这种情况下一般也是要考虑使用索引来优化的。

    4.1. actor.name未创建索引,会浏览actor整个表,保存排序关键字name和对应的id,然后排序name并检索行记录

    explain select * from actor order by name;
    

    img

    4.2. film.name建立了idx_name索引,此时查询时extra是using index

    explain select * from film order by name;
    

    img

  5. Using index:从只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的列信息。(使用覆盖索引)

    覆盖索引定义:mysql执行计划explain结果里的key有使用索引,如果select后面查询的字段都可以从这个索引的树中获取,这种情况一般可以说是用到了覆盖索引,extra里一般都有using index;覆盖索引一般针对的是辅助索引,整个查询结果只通过辅助索引就能拿到结果,不需要通过辅助索引树找到主键,再通过主键去主键索引树里获取其它字段值

explain select film_id from film_actor where film_id = 1;

img

  1. Using temporary:为了解决查询,MySQL 需要创建一个临时表来容纳结果
    1. actor.name没有索引,此时创建了张临时表来distinct
      explain select distinct name from actor;

img

​ 2.film.name建立了idx_name索引,此时查询时extra是using index,没有用临时表

explain select distinct name from film;

img

​ 3.Using where:WHERE 子句用于限制哪一个行匹配下一个表或发送到客户,并且查询的列未被索引覆盖

explain select * from actor where name = 'a';

img

Using sort_union(…), Using union(…), Using intersect(…): 这 些 函 数 说 明 如 何 为index_merge 联接类型合并索引扫描。
Using index for group-by:类似于访问表的 Using index 方式,Using index for group-by 表示MySQL发现了一个索引,可以用来查 询GROUP BY或DISTINCT查询的所有列,而不要额外搜索硬盘访问实际的表。

原文链接:(https://blog.csdn.net/zhouhengzhe/article/details/112272134)

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

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

相关文章

ArkTS #01# 组件通信

一、通过Prop单向传递/* * 单双向绑定都有 * 父组件@State,子组件@Link,孙组件@Prop * 数据流向:父组件 <--> 子组件 --> 孙组件*/@Entry @Component export struct BothBinding {@State fatherValue: number = 0//表示组件中的状态变量,这个状态变化会引起 UI 变…

风风影视安装使用

风风影视安装使用教程 一 安装软件下载风风影视 下载好后安装即可。二 配置地址1.点击设置 2.点击配置地址 3.将这串地址复制粘贴,点击确认https://gitee.com/ffddoz/tvbox1/raw/master/fantaiyingff.json到这步就可以使用了以下是功能介绍,非必须看点击主页之后,会有很多选…

idea=services启动类变成灰色了

idea启动大于5个services的时候就会让新启动的变成灰色,并且重启idea之后在services里找不到相关启动类(还要重新翻) 下面版本适用于2023.2.1+(老版本设置页在Advanced Settings中,略有不同) File----->Settings----->Advanced Settings----->Run/Debug,设置完…

常回家看看之tcachebin-attack

常回家看看之tcachebin-attack 自从glibc2.26之后出现了新的堆管理机制,及引用了tcachebin机制,tcachebin也是主要分配小堆块的,有40条bin链(0x10 - 0x410) 那么这样的分配有很多和smallbin 和fastbin重叠的部分,及malloc申请之后free掉的小堆块优先进入tcachebin中,这样…

java 面向对象1

1.java类一个类文件可以定义多个类,只能有一个用public修饰.java基本语法方面在有的很想c++.在学习java面向对象的时候我也得对比c++来学习.学习c++的三大特性:继承,多态,封装,是如何在java中体现的. 2.封装,封装是类最基础的特装类通过将好几个成员数据封装成一个整体,便于数据…

Mediawiki报错Wikimedia\Rdbms\DBQueryError的解决方案

需要运行php <你的mediawiki目录>/maintenance/update.php来更新数据库。上下文 Mediawiki登录页面报错Wikimedia\Rdbms\DBQueryError解决方法 虽然Mediawiki被墙了,很难找到官方文档,但我还是找到了Re: database problem提到的wiki-upgrade.txt。 其中,第12步指出需要…

数据中台以及数据仓库的介绍

数据中台 1、数据中台的概念数据中台是一种集中化的数据管理平台,用于整合和管理企业内部各个业务系统的数据。 它将数据从各个业务系统中抽取、清洗和集成,然后提供给其他业务系统或者数据应用进行分析、决策和创新。 数据中台的目标是实现数据的一致性、可信度和可用性,促…

常回家看看之fastbin_attack

常回家看看之fastbin_attack 原理分析 fastbin属于小堆块的管理,这里说的fastbin_attack大多指glibc2.26之前的手法,因为自glibc2.26以后,glibc迎来了一位新成员tcachebin,它减少了堆的开销,使堆管理变得迅速而高效,而且申请的小堆块会优先进入tachebin中,只有tachebin其…

触想工业显示器方案在汽车装配生产线上的应用

一、行业发展背景中国汽车工业协会数据显示,2023年我国汽车产销量双双实现历史性突破,分别达到3016.1万辆和3009.4万辆,并连续15年位居全球首位。汽车产业热销背后是先进的生产装配体系支撑,从零部件到整车,汽车的生产和工艺流程越来越复杂,涉及的自动化装配和检测设备也…

最大传输功率数学推导

最大传输功率,不仅适用于低频,也适用于高频。在个人的认知里,也同样可以用来解释高速信号的匹配原理,而不仅仅只是从阻抗不匹配造成的反射来解释。电路分析图 1. 由以上电路可知,负载功率表示如下2. 由复功率、能量守恒可知 3. 复阻抗的虚部,属于无功功率,发送等于接收…