EXPLAIN概述与字段剖析

这篇具有很好参考价值的文章主要介绍了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 语句输出的各个列的作用如下:

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) #该函数会返回一个字符串
BEGIN
    DECLARE chars_str VARCHAR(100) DEFAULT
'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ';
    DECLARE return_str VARCHAR(255) DEFAULT '';
    DECLARE i INT DEFAULT 0;
    WHILE i < n DO
        SET 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))
BEGIN
    DECLARE i INT DEFAULT 0;
    SET autocommit = 0;
    REPEAT
    SET 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_num
    END REPEAT;
    COMMIT;
END //
DELIMITER ;

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

DELIMITER //
CREATE PROCEDURE insert_s2 (IN min_num INT (10),IN max_num INT (10))
BEGIN
    DECLARE i INT DEFAULT 0;
    SET autocommit = 0;
    REPEAT
    SET 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_num
    END 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. 查询优化器可能对涉及子查询的查询语句进行重写, 转变为多表查询的操作:

EXPLAIN概述与字段剖析,数据库高级特性,数据库

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

EXPLAIN概述与字段剖析,数据库高级特性,数据库

 Union All 不需要去重 所以不创建临时表EXPLAIN概述与字段剖析,数据库高级特性,数据库

小结: 

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

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

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

  3. select_type

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

EXPLAIN概述与字段剖析,数据库高级特性,数据库

SIMPLE:

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

EXPLAIN概述与字段剖析,数据库高级特性,数据库

 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;

EXPLAIN概述与字段剖析,数据库高级特性,数据库SUBQUERY

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

EXPLAIN概述与字段剖析,数据库高级特性,数据库

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

EXPLAIN概述与字段剖析,数据库高级特性,数据库 DEPENDENT UNION

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

EXPLAIN概述与字段剖析,数据库高级特性,数据库

DERIVED  

派生表

EXPLAIN概述与字段剖析,数据库高级特性,数据库

MATERIALIZED

EXPLAIN概述与字段剖析,数据库高级特性,数据库

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;

EXPLAIN概述与字段剖析,数据库高级特性,数据库

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

EXPLAIN概述与字段剖析,数据库高级特性,数据库 eq_ref

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

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

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

EXPLAIN概述与字段剖析,数据库高级特性,数据库 从执行计划的结果中可以看出,MySQL打算将s2作为驱动表,s1作为被驱动表,重点关注s1的访问方法是 eq_ref ,表明在访问s1表的时候可以 通过主键的等值匹配 来进行访问。

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

EXPLAIN概述与字段剖析,数据库高级特性,数据库

range

使用索引获取某些范围区间的记录 EXPLAIN概述与字段剖析,数据库高级特性,数据库

index

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

当我们可以使用索引覆盖

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

EXPLAIN概述与字段剖析,数据库高级特性,数据库

小结:
结果值从最好到最坏依次是: 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

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

EXPLAIN概述与字段剖析,数据库高级特性,数据库

EXPLAIN概述与字段剖析,数据库高级特性,数据库EXPLAIN概述与字段剖析,数据库高级特性,数据库

EXPLAIN概述与字段剖析,数据库高级特性,数据库

可以看到606 会比303 更好

utf8一个字符占3个字节 

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

EXPLAIN概述与字段剖析,数据库高级特性,数据库7. Extra

太多了 不抄了 见书260文章来源地址https://www.toymoban.com/news/detail-694946.html

到了这里,关于EXPLAIN概述与字段剖析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Mysql系列】——详细剖析数据库“索引”【上篇】

        😎博客昵称:博客小梦 😊最喜欢的座右铭:全神贯注的上吧!!! 😊作者简介:一名热爱C/C++,算法,数据库等技术、喜爱运动、热爱K歌、敢于追梦的小博主! 😘博主小留言:哈喽! 😄各位CSDN的uu们,我是你的博客好友小梦,希望我的文章可以给您带来一定的帮

    2024年02月02日
    浏览(57)
  • 【数据库原理】(28)数据库设计概述

    数据库设计是为了实现数据库应用系统,涉及结构特性设计、行为特性设计和物理模式设计三个主要方面。 1. 数据库的结构特性设计 数据库的结构特性设计是数据库设计的关键,包括数据库结构的设计和建立合理的数据模型。这一部分也被称为数据库的静态结构设计。 步骤

    2024年01月19日
    浏览(53)
  • django添加数据库字段进行数据迁移

    1.修改view.py里面的变量 2.在model.py新增字段 3.打开terminal并将环境切到项目所在环境,切换方式为 4.执行命令

    2024年02月09日
    浏览(61)
  • DB(一):数据库概述、SQL概述、Oracle数据类型

    包括Oracle、DB2、SQL Server、MySQL数据库概述;数据定义语言DDL、数据操作语言DML、事务控制语言TCL、数据查询语言DQL、数据控制语言DCL语言介绍;NUMBER 、CHAR、VARCHAR2、DATE数据库类型;CHAR和VARCHAR2的存储编码、CHAR和VARCHAR2的最大长度、LONG和CLOB类型。 1、DB和DBMS (1)、数据库(

    2024年02月09日
    浏览(82)
  • 关于数据库json 字段的查询

    1、查询json字符串中是否包含某个节点 2、查询json字符串中某个节点等于或者不等于某个值 需要注意的点json串和json数组匹配方式不同 json数组匹配  $[*].name  或者 $[0].name json串 $.name 这里发现一个总结的很好的博主,推荐一下 mysql中json_extract的使用方法_-王尚可-的博客-CSDN博

    2024年02月16日
    浏览(70)
  • Mysql中的对数据库字段的数据进行加密

    注意点:此处只对name字段进行了字段类型的修改。 ENCODE(\\\'123\\\',\\\'123\\\'): 第一个123:表示插入数据库中的数据(即将要被转换的数据) 第二个123:表示转换秘钥,可以任意起名。在解密的时候会需要用到。 结果: 注意点1 :此处DECODE的两个参数分别为 需要解密的内容(数据库中

    2024年02月09日
    浏览(69)
  • 数据库字段变更监控平台设计开发

      在开发过程中,在值班解决客服问题时,在分析定位别人写的业务代码问题时, 重点是不是自己写的代码 ,只看到了数据库中落库最终数据,并不知道业务逻辑问题发生时数据库表中当时数据情况?如果能知道当时数据情况,就能更准,更快的定位到问题,可能大家对

    2024年02月15日
    浏览(65)
  • MyBatis Plus 数据库字段加密处理

    当项目开发到一半,可能突然客户会要求对数据库里面比如手机号、身份证号的字段进行加密; 在保证开发最快、影响范围最小的情况下,我们需要选择一种介于数据库和代码之间的工具来帮我们实现自动加解密; 这里我们选用AES对称加密算法,因为它是可逆算法。 AES加密

    2024年02月07日
    浏览(63)
  • mysql 查询数据库所有表,表字段

    工作中,编写xmlsql时需要查询全部字段,可以利用sql快速组装所有的列 1.查询所有的表名 2.查询某个表的所有字段 3.组装表的所有列

    2024年02月12日
    浏览(53)
  • MySQL 数据库概述

    数据(Data) 描述事物的符号记录 包括数字,文字、图形、图像、声音、档案记录等 以“记录”形式按统一的格式进行存储 表 将不同的记录组织在一起 用来存储具体数据 记录:行 字段(属性):列 数据库 表的集合,是存储数据的仓库 以一定的组织方式存储的相互有关的

    2024年02月01日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包