EXPLAIN概述与字段剖析

 6. 分析查询语句:EXPLAIN(重点)

6.1 概述

定位了查询慢的sQL之后,我们就可以使用EXPLAIN或DESCRIBE 工具做针对性的分析查询语句。DESCRIBE语句的使用方法与EXPLAIN语句是一样的,并且分析结果也是一样的。
MySQL中有专门负责优化SELECT语句的优化器模块,主要功能:通过计算分析系统中收集到的统计信息,为客户端请求的Query提供它认为最优的
执行计划(他认为最优的数据检索方式,但不见得是DBA认为是最优的,这部分最耗费时间)。
这个执行计划展示了接下来具体执行查询的方式,比如多表连接的顺序是什么,对于每个表采用什么访问方法来具体执行查询等等。MySQL为我们提供了
EXPLAIN语句来帮助我们查看某个查询语句的具体执行计划,大家看懂EXPLAIN语句的各个输出项,可以有针对性的提升我们查询语句的性能。

1.能做什么?

●表的读取顺序
●数据读取操作的操作类型

●哪些索引可以使用
●哪些索引被实际使用

●表之间的引用
●每张表有多少行被优化器查询
 

2. 版本情况

1. MySQL 5.6.3以前只能 EXPLAIN SELECT ;MYSQL 5.6.3以后就可以 EXPLAIN SELECT,UPDATE,DELETE

2. 在5.7以前的版本中,想要显示 partitions 需要使用 explain partitions 命令;想要显示

filtered 需要使用 explain extended 命令。在5.7版本后,默认explain直接显示partitions和

filtered中的信息。

6.2 基本语法

如果我们想看看某个查询的执行计划的话,可以在具体的查询语句前边加一个 EXPLAIN ,就像这样:

mysql> EXPLAIN SELECT 1;

EXPLAIN 语句输出的各个列的作用如下:

6.3 数据准备

1. 建表

表s1首先将id设为主键,  对key1 , key3 建立普通索引, 对key2建立唯一索引, 对key_part1, key_part2, key_part3按顺序建立联合索引

普通字段 common_field

CREATE TABLE s1 (
id INT AUTO_INCREMENT,
key1 VARCHAR(100),
key2 INT,
key3 VARCHAR(100),
key_part1 VARCHAR(100),
key_part2 VARCHAR(100),
key_part3 VARCHAR(100),
common_field VARCHAR(100),
PRIMARY KEY (id),
INDEX idx_key1 (key1),
UNIQUE INDEX idx_key2 (key2),
INDEX idx_key3 (key3),
INDEX idx_key_part(key_part1, key_part2, key_part3)
) ENGINE=INNODB CHARSET=utf8;CREATE TABLE s2 (
id INT AUTO_INCREMENT,
key1 VARCHAR(100),
key2 INT,
key3 VARCHAR(100),
key_part1 VARCHAR(100),
key_part2 VARCHAR(100),
key_part3 VARCHAR(100),
common_field VARCHAR(100),
PRIMARY KEY (id),
INDEX idx_key1 (key1),
UNIQUE INDEX idx_key2 (key2),
INDEX idx_key3 (key3),
INDEX idx_key_part(key_part1, key_part2, key_part3)
) ENGINE=INNODB CHARSET=utf8;

2. 设置参数 log_bin_trust_function_creators  

创建函数,假如报错,需开启如下命令:允许创建函数设置:

set global log_bin_trust_function_creators=1; # 不加global只是当前窗口有效。

 3. 创建函数

DELIMITER //
CREATE FUNCTION rand_string1(n INT)RETURNS VARCHAR(255) #该函数会返回一个字符串
BEGINDECLARE chars_str VARCHAR(100) DEFAULT
'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ';DECLARE return_str VARCHAR(255) DEFAULT '';DECLARE i INT DEFAULT 0;WHILE i < n DOSET return_str =CONCAT(return_str,SUBSTRING(chars_str,FLOOR(1+RAND()*52),1));SET i = i + 1;END WHILE;RETURN return_str;
END //
DELIMITER ;

 4. 创建存储过程

创建往s1表中插入数据的存储过程:

DELIMITER //
CREATE PROCEDURE insert_s1 (IN min_num INT (10),IN max_num INT (10))
BEGINDECLARE i INT DEFAULT 0;SET autocommit = 0;REPEATSET i = i + 1;INSERT INTO s1 VALUES((min_num + i),rand_string1(6),(min_num + 30 * i + 5),rand_string1(6),rand_string1(10),rand_string1(5),rand_string1(10),rand_string1(10));UNTIL i = max_numEND REPEAT;COMMIT;
END //
DELIMITER ;

创建往s2表中插入数据的存储过程:

DELIMITER //
CREATE PROCEDURE insert_s2 (IN min_num INT (10),IN max_num INT (10))
BEGINDECLARE i INT DEFAULT 0;SET autocommit = 0;REPEATSET i = i + 1;INSERT INTO s2 VALUES((min_num + i),rand_string1(6),(min_num + 30 * i + 5),rand_string1(6),rand_string1(10),rand_string1(5),rand_string1(10),rand_string1(10));UNTIL i = max_numEND REPEAT;COMMIT;
END //
DELIMITER ;

5. 调用存储过程

s1表数据的添加:加入1万条记录:

CALL insert_s1(10001,10000);

s2表数据的添加:加入1万条记录:

CALL insert_s2(10001,10000);

6.4 EXPLAIN各列作用

为了让大家有比较好的体验,我们调整了下 EXPLAIN 输出列的顺序。

1. table

不论我们的查询语句有多复杂,里边儿 包含了多少个表 ,到最后也是需要对每个表进行 单表访问 的,所 以MySQL规定EXPLAIN语句输出的每条记录都对应着某个单表的访问方法,该条记录的table列代表着该表的表名(有时不是真实的表名字,可能是简称)。

2. id

我们写的查询语句一般都以 SELECT 关键字开头,比较简单的查询语句里只有一个 SELECT 关键字 (大多数情况下:出现几个select就有几个id)

特殊情况:

1. 查询优化器可能对涉及子查询的查询语句进行重写, 转变为多表查询的操作:

 2.  Union 去重,  需要创建临时表(第3行), 再在其中去重

 Union All 不需要去重 所以不创建临时表

小结: 

id如果相同,可以认为是一组,从上往下顺序执行

在所有组中,id值越大,优先级越高,越先执行

关注点:id号每个号码,表示一趟独立的查询, 一个sql的查询趟数越少越好

  3. select_type

 一条大的查询语句里边可以包含若干个SELECT关键字,每个SELECT关键字代表着一个小的查询语句,而每个SELECT关键字的FROM子句中都可以包含若干张表(这些表用来做连接查询),每一张表都对应着执行计划输出中的一条记录,对于在同一个SELECT关键字中的表来说,它们的id值是相同的。
MySQL为每一个SELECT关键字代表的小查询都定义了一个称之为select_type的属性,意思是我们只要知道了某个小查询的select_type属性,就知道了这个小查询在整个大查询中扮演了一个什么角色,我们看一下select_type都能取哪些值,请看官方文档:

SIMPLE:

 查询语句不包含'UNION'或者子查询的查询都算是'SIMPLE'类型

 PRIMARY:

对于包含'UNION'或者'UNION ALL' 的大查询来说,, 他是有几个小查询组成的, 其中最左边select_typee'值就是'PRIMARY'

UNION

对于包含'UNION' 或者'UNION ALL'的大查询来说, 除了最左边的查询外, 其余的小查询的'select_type' 值就是'UNION'

UNION RESULT

MysQL 选择使用临时表来完成'UNION'查询的去重工作, 针对该临时表的查询的select_type就是UNION RESULT

mysql> EXPLAIN SELECT * FROM s1 UNION SELECT * FROM s2;

SUBQUERY

包含子查询的查询语句不能转为对应的semi-join 形式, 并且该子查询是不相关子查询,则该子查询的第一个select关键字代表的那个查询select_type 就是SUBQUERY

包含子查询的查询语句不能转为对应的semi-join 形式, 并且该子查询是相关子查询,则该子查询的第一个select关键字代表的那个查询select_type 就是DEPENDENT SUBQUERY 

 DEPENDENT UNION

在包含UINON或者UNION ALL的大查询中, 如果各个小查询都是依赖外层查询的话, 那除了最左边的那个小查询外, 其余的小查询select_type 都是 DEPENDENT UNION

DERIVED  

派生表

MATERIALIZED

4.  type

针对单表的访问方法
完整的访问方法如下: system const eq_ref ref fulltext ref_or_null
index_merge unique_subquery index_subquery range index ALL
system:
当表中只有一条记录并且该表使用的存储引擎的统计数据是精确的, 比如MyISAM, Memory,那么对该表的访问方法就是system
mysql> CREATE TABLE t(i int) Engine=MyISAM;
Query OK, 0 rows affected (0.05 sec)
mysql> INSERT INTO t VALUES(1);
Query OK, 1 row affected (0.01 sec)mysql> EXPLAIN SELECT * FROM t;

const
当我们根据主键或者一二级索引列与常数进行等值匹配时, 对单表的访问方法就是const
mysql> EXPLAIN SELECT * FROM s1 WHERE id = 10005 ;

 eq_ref

在连接查询时, 如果被驱动表是通过主键或者唯一二级索引等值匹配的方式进行访问的

(如果该主键或者唯一二级索引是联合索引的话, 所有的索引列都必须进行等值比较), 则对该被驱动表的访问方法就是eq_ref

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

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

ref
当通过普通的二级索引列与常量进行等值匹配时
mysql> EXPLAIN SELECT * FROM s1 WHERE key1 = 'a' ;

range

使用索引获取某些范围区间的记录 

index

mysql> EXPLAIN SELECT key_part2 FROM s1 WHERE key_part3 = 'a' ;

当我们可以使用索引覆盖

mysql> EXPLAIN SELECT key_part2 FROM s1 WHERE key_part3 = 'a';

小结:
结果值从最好到最坏依次是: system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
其中比较重要的几个提取出来(见上图中的蓝 色)。 SQL 性能优化的目标:至少要达到 range 级别,要求是 ref 级别,最好是 consts 级别。(阿里巴巴 开发手册要求)

5. possible_keyskey

 可能用到的索引和 实际上使用的索引

 6. key_len

实际使用到的索引长度(即:字节数)  

可以看到606 会比303 更好

utf8一个字符占3个字节 

303 = 允许长度100 * 3 + 一个字节(null) + 两个字节变长字段

7. Extra

太多了 不抄了 见书260

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

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

相关文章

Centos 7 通过Docker部署OnlyOffice

前言&#xff1a; 在本文中&#xff0c;我们将详细介绍如何使用 Docker 部署功能强大的协作办公套件 OnlyOffice。通过 Docker&#xff0c;您可以轻松构建、部署和管理 OnlyOffice&#xff0c;从而提高团队协作和企业办公的效率。 一、安装Docker 1、向系统添加Docker CE软件仓…

51单片机DHT11温湿度控制系统仿真设计( proteus仿真+程序+原理图+报告+讲解视频)

51单片机DHT11温湿度控制系统仿真设计 1.主要功能&#xff1a;2.仿真3. 程序代码4. 原理图元器件清单5. 设计报告6. 设计资料内容清单&下载链接 51单片机DHT11温湿度控制系统仿真设计( proteus仿真程序原理图报告讲解视频&#xff09; 仿真图proteus8.9及以上 程序编译器&…

通过cpolar内网穿透,在家实现便捷的SSH远程连接公司内网服务器教程

文章目录 1. Linux CentOS安装cpolar2. 创建TCP隧道3. 随机地址公网远程连接4. 固定TCP地址5. 使用固定公网TCP地址SSH远程 本次教程我们来实现如何在外公网环境下&#xff0c;SSH远程连接家里/公司的Linux CentOS服务器&#xff0c;无需公网IP&#xff0c;也不需要设置路由器。…

中国手机新进程:折叠屏出海的荣耀,5G中回归的华为

最近&#xff0c;“华为5G回归”“自研麒麟芯片回归”的消息引爆网络。网友开心庆贺之余&#xff0c;也纷纷猜测&#xff0c;华为强势归来&#xff0c;哪家友商最慌&#xff1f; “华为的回归&#xff0c;让竞争充满了更多的可能性和更多的魅力”&#xff0c;与华为渊源颇深的…

mac常见问题(五) Mac 无法开机

在mac的使用过程中难免会碰到这样或者那样的问题&#xff0c;本期为您带来Mac 无法开机怎么进行操作。 1、按下 Mac 上的电源按钮。每台 Mac 电脑都有一个电源按钮&#xff0c;通常标有电源符号 。然后检查有没有通电迹象&#xff0c;例如&#xff1a; 发声&#xff0c;例如由风…

算法:合并两个有序数组---双指针[1]

1、题目&#xff1a; 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&#xff0c;使合并后的数组同样按 非递减顺序 排列。 注意&#xff1a;最终&a…

MAC系统“无法验证开发者”问题

参考:https://blog.csdn.net/suxiang198/article/details/126550955 对于使用MAC电脑的同学而言&#xff0c;许多时候因为使用需要&#xff0c;从第三方源&#xff08;比如github等&#xff09;下载工具或软件&#xff0c;而在运行时会受到MAC系统的安全限制&#xff0c;老是弹…

【数据结构篇】线性表1 --- 顺序表、链表 (万字详解!!)

前言&#xff1a;这篇博客我们重点讲 线性表中的顺序表、链表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列... 线性表在逻辑上是…

Python操作Excel教程(图文教程,超详细)Python xlwings模块详解,

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;小白零基础《Python入门到精通》 xlwings模块详解 1、快速入门1、打开Excel2、创建工作簿2.1、使用工作簿2.2、操作…

修复中间件log4j漏洞方案(直接更换漏洞jar包)

说明&#xff1a; 后台服务里面的log4j漏洞我们已经全部升级处理了&#xff0c;但是一些中间件镜像包里的log4j漏洞需要单独处理 解决办法以ElasticSearch7.6.2为例&#xff1a; 方法&#xff1a; &#xff08;1&#xff09;找到容器里面有哪些旧的log4j依赖包 &#xff08;…

css网格布局

css网格布局 常用属性 display: grid; //开启网格grid-template-columns: 2fr 1fr 1fr 1fr 1fr; //设置多少列每列宽度grid-gap: 10px; // 设置表格之间间距grid-template-rows: 50px 50px 50px 50px; // 设置多少行 每行的高度grid-column : 1 //占据位置 占据1格grid-colu…

【LeetCode-中等题】207. 课程表

文章目录 题目方法一&#xff1a;bfs广度优先 有向图的拓扑排序&#xff08;入度&#xff09;方法二&#xff1a;dfs 深度优先搜索 题目 此题就可以转换为&#xff0c;求一个有向图是否存在环&#xff1b; 存在环&#xff0c;拓扑排序得出的结果是不完整的&#xff0c; 如果不…

数据结构与算法-插入希尔归并

一&#xff1a;排序引入 我们通常从哪几个方面来分析一个排序算法&#xff1f; 1.时间效率&#xff1a;决定了算法运行多久&#xff0c;O&#xff08;1&#xff09; 2.空间复杂度&#xff1a; 3.比较次数&交换次数:排序肯定会牵涉到两个操作&#xff0c;一个比较是肯定的。…

Java elasticsearch scroll模板实现

一、scroll说明和使用场景 scroll的使用场景&#xff1a;大数据量的检索和操作 scroll顾名思义&#xff0c;就是游标的意思&#xff0c;核心的应用场景就是遍历 elasticsearch中的数据&#xff1b; 通常我们遍历数据采用的是分页&#xff0c;elastcisearch还支持from size的方…

mybatis-generator-maven-plugin使用

前提说明 数据库&#xff1a;MYSQL57Mybatis : http://mybatis.org/generator/index.html 操作说明 引入插件 <plugins><!-- MyBatis 逆向工程 插件 --><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generat…

汽车电子系统网络安全解决方案

声明 本文是学习GB-T 38628-2020 信息安全技术 汽车电子系统网络安全指南. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 汽车电子系统网络安全范围 本标准给出了汽车电子系统网络安全活动框架&#xff0c;以及在此框架下的汽车电子系统网络安全活动…

E5061B/是德科技keysight E5061B网络分析仪

181/2461/8938产品概述 是德科技E5061B(安捷伦)网络分析仪在从5 Hz到3 GHz的宽频率范围内提供通用的高性能网络分析。E5061B提供ENA系列常见的出色RF性能&#xff0c;还提供全面的LF(低频)网络测量能力&#xff1b;包括内置1 Mohm输入的增益相位测试端口。E5061B从低频到高频的…

Xcode打包ipa文件,查看app包内文件

1、Xcode发布ipa文件前&#xff0c;在info中打开如下两个选项&#xff0c;即可在手机上查看app包名文件夹下的文件及数据。

Tiny Player Mac:小而美,音乐播放的极致体验

对于追求音质和操作简便的Mac用户来说&#xff0c;Tiny Player Mac是一款不可多得的音乐播放器。它以简洁的界面、强大的功能和优异的性能&#xff0c;吸引了无数用户的目光。接下来&#xff0c;让我们一起了解这款小而美的音乐播放器。 Tiny Player Mac支持多种音频格式&#…

无需租云服务器,Linux本地搭建web服务,并内网穿透发布公网访问

文章目录 前言1. 本地搭建web站点2. 测试局域网访问3. 公开本地web网站3.1 安装cpolar内网穿透3.2 创建http隧道&#xff0c;指向本地80端口3.3 配置后台服务 4. 配置固定二级子域名5. 测试使用固定二级子域名访问本地web站点 前言 在web项目中,部署的web站点需要被外部访问,则…