explain详解

你的名字 2022-11-30 04:13 343阅读 0赞

explain是干嘛的?

使用explain可以模拟优化器执行sql语句,分析查询语句的结构,是否使用索引等等

使用方法:
在查询语句select关键字前面加上explain关键字,如下图的格式,然后就会返回分析的结果

在这里插入图片描述
下面来详解使用explain后返回的数据字段的含义

首先这是表结构:

  1. DROP TABLE IF EXISTS `actor`; 3 CREATE TABLE `actor` ( 4 `id` int(11) NOT NULL, 5 `name` varchar(45) DEFAULT NULL, 6 `update_time` datetime DEFAULT NULL, 7 PRIMARY KEY (`id`) 8 ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 910 INSERT INTO `actor` (`id`, `name`, `update_time`) VALUES (1,'a','2017‐12‐22 15:27:18'), (2,'b','20 17‐12‐22 15:27:18'), (3,'c','2017‐12‐22 15:27:18'); 1112 DROP TABLE IF EXISTS `film`; 13 CREATE TABLE `film` ( 14 `id` int(11) NOT NULL AUTO_INCREMENT, 15 `name` varchar(10) DEFAULT NULL, 16 PRIMARY KEY (`id`), 17 KEY `idx_name` (`name`) 18 ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 1920 INSERT INTO `film` (`id`, `name`) VALUES (3,'film0'),(1,'film1'),(2,'film2'); 2122 DROP TABLE IF EXISTS `film_actor`; 23 CREATE TABLE `film_actor` ( 24 `id` int(11) NOT NULL, 25 `film_id` int(11) NOT NULL, 26 `actor_id` int(11) NOT NULL, 27 `remark` varchar(255) DEFAULT NULL, 28 PRIMARY KEY (`id`), 29 KEY `idx_film_actor_id` (`film_id`,`actor_id`) 30 ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 3132 INSERT INTO `film_actor` (`id`, `film_id`, `actor_id`) VALUES (1,1,1),(2,1,2),(3,2,1);
  1. id字段列:

id有几个就代表这个sql语句被解析成多少个select. 其中id越大,代表执行的优先级别越高,id相等则从上到下依次执行,id为NULL的最后执行

  1. explain select * from film t1 left join film_actor t2 on t1.id=t2.film_id;

在这里插入图片描述
2.select_type字段列:代表查询的语句的复杂类型
1).simple:简单查询
2).primary:复合查询的最外层查询
3).subquery:是select 后面的子查询

  1. explain select (select 1 from actor where id = 1);

在这里插入图片描述

4).derived是紧跟在from后面的子查询,MySQL会将结果存放在一个临时表中,也称为派生表
在这里插入图片描述
为什么这里查出来的是一个简单的语句呢?而不是想象中的derived类型呢,原因很简单,在mysql5.7以后,对派生表进行优化了,优化器引入derived_merge。当然我们也可以通过设置参数将派生表优化给关闭。

  1. set optimizer_switch='derived_merge=off'

在这里插入图片描述
5)union:紧跟union后面的select
3.table字段列:表示访问的是哪一个表
4.type列:表示MYSQL决定如何查找表中的行。
他有七个级别,依次从最优到最差分别为:system>const>eq_red>red>range>index>ALL
一般来说,最好达到ref级别,实在达不到,range级别也不差。
1)NULL:当type为null时,表示查询语句在执行过程中被优化,不用访问表,直接从索引中得到值

  1. EXPLAIN SELECT min(id) from film;

在这里插入图片描述
2)const:表示对查询的部分进行优化,并将其转化为一个常量。用于primary key 或者unique key的所有列与常量比较时,所以表中只有一条记录,查询速度快。

  1. EXPLAIN SELECT *from film where id =1;

在这里插入图片描述
3)eq_ref:primary key 或者unique key 索引的所有部分被连接使用,最多只返回一条符合条件的记录。

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

在这里插入图片描述
4)ref:相比rq_ref,不使用唯一索引,而是使用普通索引或者唯一性索引的部分前缀,索引要和某个值相比较,可能会找到多个符合条件的行

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

在这里插入图片描述
5)range:范围扫描通常出现在in(),between,>,<,>=等操作中。

  1. explain select * from actor where id > 1;

在这里插入图片描述
6)index:扫描全索引,一般是扫描某个二级索引,她不会从索引根节点查找,而是直接对二级索引的叶子节点遍历和扫描。速度较慢。这种一般为使用了覆盖索引,二级索引一般比较小。(因为select * 这里面包含二级索引字段,所以就会走二级索引)

  1. explain select * from film;

7)all:即全表扫描,扫描聚集索引下的所有叶子节点,因为select * 这里面的字段都没有建立除了聚集索引外的索引,所以就只会走聚集索引,如果不知道聚集索引的可以去看一下这篇博文(https://editor.csdn.net/md/?articleId=107474948),因为聚集索引叶子节点存了data数据多,所以效率就会低

  1. explain select * from actor;

在这里插入图片描述
5.possible_keys列
表示该查询语句可能使用哪个索引,如果为NULL,则表明没有相关索引以供查询,这时候可以在where语句后面字段加个索引,看是否提高了性能
6.key列
表示实际用了哪个索引,如果possible_keys不为空,key为null,说明数据少,不需要走索引,直接全表扫描。
7.key_len列
这表示用到的索引字段的字节数

计算规则如下:
(当然,索引的最大长度为768,如果超过了这个长度,mysql会做一个类似左前缀索引的处理,将前半部分的字符提取出来做索 引。)


字符串 :

  • char(n):n字节长度
  • varchar(n):如果是utf-8,则长度 3n + 2 字节,加的2字节用来存储字符串长度

数值类型:

  • tinyint:1字节
  • smallint:2字节
  • int:4字节
  • bigint:8字节

时间类型:

  • date:3字节
  • timestamp:4字节
  • datetime:8字节
  • 如果字段允许为 NULL,需要1字节记录是否为 NULL

8. ref列
这一列显示了在key列记录的索引中,表查找值所用到的列或常量,常见的有:const(常量),字段名(例:film.id)
9. rows列
这一列是mysql估计要读取并检测的行数,注意这个不是结果集里的行数。
10. Extra列
这一列展示的是额外信息。常见的重要值如下
1)Using index:使用覆盖索引 覆盖索引定义:如果select后面查询的字段都可以从这个索引的树中 获取,这种情况一般可以说是用到了覆盖索引,extra里一般都有using index;覆盖索引一般针对的是辅助索引,整个 查询结果只通过辅助索引就能拿到结果,不需要通过辅助索引树找到主键
在这里插入图片描述
2)Using where:where后面查询的字段没有建立索引,使用 where 语句来处理结果
在这里插入图片描述
3)Using index condition:查询的列不完全被索引覆盖,where条件中是一个前导列的范围;
在这里插入图片描述
4)Using temporary:mysql需要创建一张临时表来处理查询。出现这种情况一般是要进行优化的,首先是想到用索 引来优化
5)Using filesort:将用外部排序而不是索引排序,数据较小时从内存排序,否则需要在磁盘完成排序。这种情况下一 般也是要考虑使用索引来优化的。
6)Select tables optimized away:使用某些聚合函数(比如 max、min)来访问存在索引的某个字段是

发表评论

表情:
评论列表 (有 0 条评论,343人围观)

还没有评论,来说两句吧...

相关阅读

    相关 explain详解

    explain是干嘛的? 使用explain可以模拟优化器执行sql语句,分析查询语句的结构,是否使用索引等等 使用方法: 在查询语句select关键字前面加上expl

    相关 MySQL Explain详解

    最近慢慢接触MySQL,了解如何优化它也迫在眉睫了,话说工欲善其事,必先利其器。最近我就打算了解下几个优化MySQL中经常用到的工具。今天就简单介绍下EXPLAIN。 内容

    相关 mysql explain详解

    explain显示了mysql如何使用索引来处理select语句以及连接表。可以帮助选择更好的索引和写出更优化的查询语句。 先解析一条sql语句,看出现什么内容 `EXPL