SQL优化之EXPLAIN执行计划(转载)

目录

  • 第一章、快速了解EXPLAIN
    • 1.1)EXPLAIN是什么
    • 1.2)示例
  • 第二章、结果列说明
    • 2.1)id 与table
    • 2.2)select_type:
    • 2.3)type
    • 2.4)possible_keys与key
    • 2.5) key_len
    • 2.6)rows
    • 2.7)Extra
  • 第三章、转载自:

友情提醒:
先看文章目录,大致了解文章知识点结构,点击文章目录可直接跳转到文章指定位置。转载自:SQL优化之EXPLAIN执行计划

第一章、快速了解EXPLAIN

1.1)EXPLAIN是什么

EXPLAIN可以帮助开发人员分析SQL问题,EXPLAIN显示了MySQL如何使用使用SQL执行计划,可以帮助开发人员写出更优化的查询语句。使用方法,在select语句前加上EXPLAIN就可以知道:

表的读取顺序数据读取操作的操作类型哪些索引可以使用哪些索引被实际使用表之间的引用每张表有多少行被优化器查询

1.2)示例

下面是一个最普通的查询语句,用EXPLAIN进行分析演示。

EXPLAIN select * from TableName;

会得到以下结果:
在这里插入图片描述
除了以SELECT开头的查询语句,其余的DELETE、INSERT、REPLACE以及UPOATE语句前边都可以加上EXPLAIN

第二章、结果列说明

2.1)id 与table

id :SELECT识别符。这是SELECT查询序列号。在一个大的查询语句中每个SELECT关键字都对应一个唯一的id。
①查询中包含子查询的情况

EXPLAIN
SELECT * FROM s1 WHERE id IN (SELECT id FROM s2) OR order_no = 'a';

在这里插入图片描述
这里虽然我们的查询语句是一个子查询,但是执行计划中s1和s2表对应的记录的id值全部是1,这就表明了查询优化器对查询语句进行重写,将子查询转换为了连接查询。

②查询中包含UNION语句的情况

SELECT * FROM s1
UNION SELECT * FROM s2 ;

在这里插入图片描述
这个语句的执行计划的第三条记录为什么这样?UNION子句会把多个查询的结果集合并起来并对结果集中的记录进行去重,怎么去重呢? MySQL使用的是内部的临时表。正如上边的查询计划中所示,UNION 子句是为了把id为1的查询和id为2的查询的结果集合并起来并去重,所以在内部创建了一个名为<union1,2>的临时表(就是执行计划第三条记录的table列的名称),id为NULL表明这个临时表是为了合并两个查询的结果集而创建的。

③查询中包含UNION all的情况

EXPLAIN
SELECT * FROM s1 UNION ALL SELECT * FROM s2;

在这里插入图片描述

跟UNION 对比起来,UNION ALL就不需要为最终的结果集进行去重,它只是单纯的把多个查询的结果集中的记录合并成一个并返回给用户,所以也就不需要使用临时表。所以在包含UNION ALL子句的查询的执行计划中,就没有那个id为NULL的记录

table :每条记录都对应着某个单表,该条记录的table列,代表着该表的表名。
在这里插入图片描述

2.2)select_type:

select_type: 表示SELECT语句的类型。

simple:简单select(不使用union或子查询)。

primary:对于包含union union all 或者子查询的大查询来说,最左边查询的select type 值为primary

union:对于包含union或者union all的大查询来说,除了最左边的那个查询以外,其余小查询的select type值为union

dependent union:在包含union 或者 union all的大查询中,如果各个小查询都依赖外层查询的话,除了最左边的那个小查询外,其余的select type为dependent union

union result:mysql使用临时表来完成union的去重工作,针对该临时表(union的结果)的查询的select type为union result

subquery:包含子查询的查询语句不能够转为对应的半连接形式,并且该查询不是相关子查询,查询优化器决定采用该子查询物化的方案来执行该子查询时,该子查询的第一个select关键字对应的select_type为subquery

dependent subquery:包含子查询的查询语句不能够转为对应的半连接形式,并且该查询是相关子查询,该子查询的第一个select关键字对应的select_type为dependent subquery

derived:采用物化的方式执行包含派生表的查询,该派生表对应的自查询的select_type就是derived

2.3)type

type:显示连接使用了何种类型。从最好到最差的连接类型为:system > const > eq_ref > ref > ref_or_null >range > index > ALL。一般来说,得保证查询至少达到range级别,最好能达到ref。

system:表仅有一行,这是const类型的特列,平时不会出现,这个也可以忽略不计。

const:当我们根据主键或者唯一二级索引列与常数进行等值匹配时,对单表的访问方法就是const。因为只匹配一行数据,所以很快。
例如将主键置于where列表中


-- 通过主键和常数值进行比较
EXPLAIN
select * from single_table where id = 400;-- 通过唯一二级索引和常数值进行比较
EXPLAIN
select * from single_table where key2 = 100;

注意:如果主键或者唯一二级索引的索引列由多个列组成,则只有在索引列中的每一项都与常数进行等值比较时,这个const访问方法才有效(因为只有这样才能保证最多只有一条记录符合条件)

eq_ref:在连接查询时,如果被驱动表是通过主键或者唯一二级索引列等值匹配的方式进行访问的,则对该被驱动表的访问方法就是eq_ref。
(驱动表与被驱动表:A表和B表join连接查询,如果通过A表的结果集作为循环基础数据,然后一条一条地通过该结果集中的数据作为过滤条件到B表中查询数据,然后合并结果。那么我们称A表为驱动表(作为外层循环),B表为被驱动表(里层循环,需要不断的拿外层循环传进来的每条记录去匹配))
左连接中,左表是驱动表
右连接中,右表是驱动表
内连接中,mysql会自动选择数据量较小的表作为驱动表。

EXPLAIN
SELECT * FROM s1 INNER JOIN s2 ON s1.id = s2.id;

在这里插入图片描述
从执行计划的结果中可以看出,MySQL打算将s2作为驱动表,s1作为被驱动表,重点关注s1的访问方法是eq_ref,表明在访问s1表的时候可以通过主键的等值匹配来进行访问。

ref:普通的二级索引列与常数等值比较,那么对该表的访问方法就可能是ref。
对于普通的二级索引来说,通过索引列进行等值比较后可能匹配到多条连续的记录,而不是像主键或者唯一二级索引那样最多只能匹配1条记录,所以这种ref访问方法比const要差些,但是在二级索引等值比较时匹配的记录数较少时的效率还是很高的(如果匹配的二级索引记录太多那么回表的成本就太大了)。

EXPLAIN
SELECT * FROM s1 WHERE order_no = 'a';

在这里插入图片描述

ref_or_null:同时找出某个二级索引列的值等于某个常数值的记录,并且把该列中值为null的记录也找出来

select * from single_table where key1 = 'abc' or key1 is null

range:如果索引列并不全是等值查询的时候,还进行范围匹配的访问,为range利用索引,一般就是在你的where语句中出现了between、<、>、in等的查询。
这种范围扫描索引扫描比全表扫描要好,因为它只需要开始于索引的某一点,而结束于另一点,不用扫描全部索引。

select * from single_table where key_part1 = 'a' AND key_part2 > 'b';
EXPLAIN
SELECT * FROM s1 WHERE order_no IN ('a', 'b', 'c');EXPLAIN
SELECT * FROM s1 WHERE order_no > 'a' AND order_no < 'b';

在这里插入图片描述

index:当我们可以使用索引覆盖,但需要扫描全部的索引记录时,该表的访问方法就是index。

EXPLAIN
SELECT insert_time FROM s1 WHERE expire_time = '2021-03-22 18:36:47';

在这里插入图片描述

ALL:对于每个来自于先前的表的行组合,进行完整的表扫描(性能最差)。

EXPLAIN
SELECT * FROM s1;

在这里插入图片描述

2.4)possible_keys与key

possible_keys:指出MySQL能使用哪个索引在该表中找到行。如果是空的,没有相关的索引。这时要提高性能,可通过检验WHERE子句,看是否引用某些字段,或者检查字段不是适合索引。

key:实际使用到的索引。如果为NULL,则没有使用索引。如果为primary的话,表示使用了主键。

EXPLAIN SELECT order_note FROM s1 WHERE
insert_time = '2021-03-22 18:36:47';

在这里插入图片描述
上述执行计划的possible keys列的值表示该查询可能使用到u_idx_day_status,idx_insert_time两个索引,然后key列的值是u_idx_day_status,表示经过查询优化器计算使用不同索引的成本后,最后决定使用u_idx_day_status来执行查询比较划算。

2.5) key_len

MySQL在执行计划中输出key_len列主要是为了让我们区分某个使用联合索引的查询具体用了几个索引列(复合索引有最左前缀的特性,如果复合索引能全部使用上,则是复合索引字段的索引长度之和,这也可以用来判定复合索引是否部分使用,还是全部使用),而不是为了准确的说明针对某个具体存储引擎存储变长字段的实际长度占用的空间到底是占用1个字节还是2个字节。

2.6)rows

rows 预估的需要读取的记录条数

EXPLAIN
SELECT * FROM s1 WHERE order_no > 'z';EXPLAIN
SELECT * FROM s1 WHERE order_no > 'a';

在这里插入图片描述
我们看到执行计划的rows列的值是分别是1和10573,这意味着查询优化器在经过分析使用查询的成本之后,觉得满足order_no> 'z’这个条件的记录只有1条,觉得满足order_no> ’ a '这个条件的记录有10573条。

2.7)Extra

Extra :说明—些额外的信息 ,该列包含MySQL解决查询的详细信息。

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

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

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

Using filesort:MySQL需要额外的一次传递,以找出如何按排序顺序检索行。

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

Using temporary:为了解决查询,MySQL需要创建一个临时表来容纳结果。

Using where:WHERE 子句用于限制哪一个行匹配下一个表或发送到客户。

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查询的所有列,而不要额外搜索硬盘访问实际的表。

第三章、转载自:

SQL优化之EXPLAIN执行计划

Explain执行计划

MySQL实战:explain详解(上)
基本每个文章写的都不全,只好各复制增删修改了一些,但是其实还是不全,只能了解个大概了。有兴趣的还是买个书看看吧。

ps:凌晨四点写的,看着墙上的小强陷入了沉思。

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

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

相关文章

遥感图像处理:从畸变消除到专题信息提取

​ ​ ​在遥感技术的应用中&#xff0c;图像处理是不可或缺的关键步骤。从消除各种辐射畸变和几何畸变&#xff0c;到利用增强技术突出景物的光谱和空间特征&#xff0c;再到进一步理解、分析和判别处理后的图像&#xff0c;这一过程为我们呈现了一幅幅更为真实、清晰的…

500元以下户外运动耳机哪款好?五大绝佳好货推荐

户外运动已经成为许多人日常生活的一部分&#xff0c;无论是晨跑、骑行还是徒步&#xff0c;音乐总能为我们带来无尽的活力与乐趣&#xff0c;而一款优质的户外运动耳机&#xff0c;更是能为我们带来沉浸式的音乐体验&#xff0c;让运动更加充满激情&#xff0c;那么如何在500元…

紧急 CCF-C ICPR 2024摘要投稿日期延期至4月10日 速投速成就科研梦

会议之眼 快讯 第27届ICPR&#xff08;The International Conference on Pattern Recognition&#xff09;即国际模式识别会议将于 2024年 12月1日-5日在印度加尔各答的比斯瓦孟加拉会议中心举行&#xff01;ICPR是国际模式识别协会的旗舰会议&#xff0c;也是模式识别、计算机…

【可视化大屏开发】17. 加餐-ECharts定制省份地图

各身份地图数据下载小工具 DataV.GeoAtlas地理小工具系列 登录DataV 后&#xff0c;直接通过选择点击获取需要的省份地区数据 > 其实单击即可完成选择 检查下载的数据格式是否正常 自定义字体 更新地图部分代码 index.less部分 //声明字体 font-face{ font-family: …

农资行业短视频宣传怎么做?小魔推打造高效农业矩阵!

近年来传统农业正在经历一场改革&#xff0c;不论是生产方式还是消费需求&#xff0c;农资行业都发生了翻天覆地的变化。而且从去年到今年农业涌现出了一些新玩法&#xff0c;结合这些新玩法&#xff0c;更是能够改变农资行业的宣传与盈利模式&#xff01; 前几天梳理的小魔推…

btSoftRigidDynamicsWorld 类是 Ammo.js 物理库中的一个类,表示一个动态世界,用于处理软体和刚体物体的物理模拟。

demo案例 btSoftRigidDynamicsWorld 类是 Ammo.js 物理库中的一个类&#xff0c;表示一个动态世界&#xff0c;用于处理软体和刚体物体的物理模拟。让我们按照输入参数、输出、属性和方法来详细解释其 API&#xff1a; 输入参数&#xff1a; dispatcher&#xff1a;这是一个…

一天300收入打底,​一个适合任何人的创业项目!

共享旅游卡项目&#xff0c;一天300收入打底&#xff0c;一个适合任何人的创业项目&#xff01; 只要你不懒&#xff0c;生活总过得不会太差。只要你不贪&#xff0c;就算不能大富大贵&#xff0c;至少不会负债累累。 人性最难戒掉的两个字&#xff1a;一个是懒&#xff0c;另…

理解 编译和链接

目录 1. 翻译环境和运行环境 2. 翻译环境 2.1 预处理&#xff08;预编译&#xff09; 2.2 编译 2.2.1 词法分析&#xff1a; 2.2.2 语法分析 2.2.3 语义分析 2.3 汇编 2.4 链接 3. 运行环境 1. 翻译环境和运行环境 在ANSI C的任何一种实现中&#xff0c;存在两个不同…

Hystrix:实现分布式系统的延迟处理和容错保护机制

文章目录 一、Hystrix的概念与作用1.1、资源隔离1.2、熔断器模式1.3、命令模式1.4、监控和报警 二、Hystrix的使用方法三、总结 一、Hystrix的概念与作用 Hystrix是Netflix开源的一个库&#xff0c;用于处理分布式系统中的延迟和容错。它通过在服务调用之间添加保护机制&#…

分享5个好用的ChatGPT

目录 1、ChatGPT Web (cnote.top) 2、Gnomic智能体平台|AI Agent|CarrotAI大模型 3、Ymiai-快捷、高效的人工智能创作平台 4、chatAI中文版 5、智能助手 1、ChatGPT Web (cnote.top) https://f1.cnote.top/#/chat/1002 2、 Gnomic智能体平台|AI Agent|CarrotAI大模型 https:/…

五、书架开发--1.书架标题组件交互、获取书架数据

添加书架页面&#xff0c;做路由配置 首先添加书架页面&#xff0c;到views中的store中添加一个StoreShelf表示书架 然后到路由中进行注册 然后书城首页的返回键我们是想要点击返回的话就跳转到书架页面&#xff0c;所以如下this.$router.push(/store/shelf) 做书架标题组件 …

MySQL数据库的详解(1)

DDL&#xff08;数据库操作&#xff09; 查询 查询所有数据库&#xff1a;show databases;当前数据库&#xff1a;select database(); 创建 创建数据库&#xff1a;create database [ if not exists] 数据库名 ; 使用 使用数据库&#xff1a;use 数据库名 ; 删除 删除数…