MySQL基础学习: 第四章 使用EXPLAIN查看执行计划详解分析

一、EXPLAIN语句的作用

在客户端执行MySQL的操作语句,会依次经过MySQL客户端连接管理、语法解析与优化(查询缓存、语法解析、查询优化)、存储引擎层。其中查询优化器在基于成本和规则对查询语句进行优化,并且在优化后会生成一个执行计划。MySQL提供了EXPLAIN语句来查看查询语句经过查询优化器优化后的执行计划。
在这里插入图片描述
定义本章所使用的表结构:

CREATE TABLE `source_learn` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  `data_type` enum('oracle’,'mysql') DEFAULT 'oracle' COMMENT '源类型',
  `name` varchar(100) NOT NULL COMMENT '源名称',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

CREATE TABLE `source_learn_param` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增id',
  `source_id` bigint(20) NOT NULL COMMENT '关联源id',
  `key` varchar(50) NOT NULL COMMENT '参数key',
  `value` text NOT NULL COMMENT '参数值',
  `data_type` enum('oracle','mysql') DEFAULT 'oracle' COMMENT '源类型',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `source_id_index` (`source_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

CREATE TABLE `table_test_learn` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `source_id` bigint(20) DEFAULT NULL COMMENT '源id',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='元数据';


二、EXPLAIN语句的属性含义及作用

EXPLAIN语句包含如下属性列:

属性名说明
id每个SELECT对应的唯一id
select_type每个SELECT对应的查询类型
table表名称
paritions分区信息
type单表的访问方法
possible_keys可能使用到的索引
key实际使用的索引
key_len实际使用到的索引长度
ref
rows预计要读取到的记录数量
filtered
Extra额外的一些信息

1、id

在查询语句(经过查询优化器优化后的查询语句)中可能会包含多个SELECT语句,每个select语句都会对应一个唯一的id。并且查询计划会为每个表生成一个记录,但是这些记录的id可能存在相同的情况。
(1)简单的SELECT语句

explain select id,name from source_learn where data_type = 'oracle';

在这里插入图片描述
(2)包含子查询的SELECT语句

EXPLAIN select * from table_test_learn as test where test.source_id in (select source_learn.id from source_learn where source_learn.data_type = 'oracle');

在这里插入图片描述
可以看到这个子查询语句生成的执行计划中包含两条记录,这两条的分别对应表table_test_learn和表source_learn。这个查询语句包含了两个SELECT查询语句为什么id值是相同的呢?这里的id相同表示着:通过查询优化器对查询语句的优化,将子查询语句转变成了连接查询语句。

2、select_type

在一个查询语句中可能包含多个小的查询语句,在MySQL中每个小的查询语句都包含select_type属性,通过该属性的取值,我们可以判断出这个小的查询语句在整个查询语句中扮演着一个什么样的角色。该属性的取值如下:

取值说明
SIMPLE没有UNION或查询优化器优化后不包含子查询的语句
PRIMARY包含联合查询或查询优化器优化后包含子查询的,第一条记录的select_type的取值就是PRIMARY
UNION查询语句包含联合查询,除了第一个记录外,其余记录的select_type的取值是UNION
UNION RESULT对于UNION操作产生的临时表的select_type的取值为UNION RESULT
SUBQUERY对于非相关子查询的记录的select_type的取值为SUBQUERY
DEPENDENT SUBQUERY对于相关子查询的记录的select_type的取值为DEPENDENT SUBQUERY
DEPENDENT UNION
DERIVED
MATERIALIZED对于包含子查询的语句,存在需要将子查询物化后再参与连接查询,此时的select_type的取值为MATERIALIZED

(1)SIMPLE

下面展示了内连接查询语句的执行计划,在查询语句中不包含UNION和子查询,因此两条记录的select_type的取值都是SIMPLE。

EXPLAIN select * from source_learn inner join source_learn_param on source_learn.id = source_learn_param.source_id;

在这里插入图片描述

(2)PRIMARY、UNION、UNION RESULT

下面展示了查询语句中使用UNION关键字,其中语句最左边的是PRIMARY,其余的查询是UNION,UNION RESULT表示的是对于UNION的语句处理使用了临时表进行了去重处理。

EXPLAIN select data_type from source_learn UNION select data_type from source_learn_param;

在这里插入图片描述
下面展示了查询语句中使用了UNION ALL关键字执行计划详情
UNION ALL不会进行去重处理,因此没有产生临时表。

EXPLAIN select data_type from source_learn UNION ALL select data_type from source_learn_param;

在这里插入图片描述

(5)SUBQUERY

下面展示了查询语句在字段中使用了子查询操作,在左边的查询语句的的select_type为PRIMARY。剩下的一个查询语句查询优化器并为对其优化成连接查询的形式,并且改查询语句为非相关子查询,因此select_type为SUBQUERY。

EXPLAIN select source_learn.data_type, (select DISTINCT(source_id) from source_learn_param where source_learn_param.id = 1) as key_source_id from source_learn;

在这里插入图片描述

(6)DEPENDENT SUBQUERY

下面展示的是相关子查询查询计划记录的select_type的取值为DEPENDENT SUBQUERY。

  • where条件后面的相关子查询语句
EXPLAIN select source_learn.data_type from source_learn where source_learn.id in (select source_id from table_test_learn) or source_learn.data_type = "oracle";

在这里插入图片描述

  • 字段为相关子查询的语句
EXPLAIN select source_learn.data_type, (select DISTINCT(source_id) from source_learn_param where source_learn_param.data_type = source_learn.data_type) as key_source_id from source_learn;

在这里插入图片描述

(7)DEPENDENT UNION

在存在UNION的查询语句中如果各个子查询语句间存在依赖关系,者除了第一个记录的select_type为PRIMARY,其他的子查询语句记录中的select_type为DEPENDENT UNION

EXPLAIN select * from source_learn where id in (select source_id from source_learn_param where data_type = "oracle" UNION select id from source_learn where name='oracle_source')

在这里插入图片描述

(8)DERIVED

(9)MATERIALIZED

下面的查询语句展示了表table_test_learn子查询物化后参与连接查询。

EXPLAIN (select data_type from source_learn where source_learn.id in (select source_id from table_test_learn)) UNION ALL select data_type from source_learn_param;

在这里插入图片描述

3、table

无论我们写的SQL语句有多复杂,最终都会对单个表进行查询操作,查询计划会为每个表生成一条记录,记录中的table列就表示表的名字。

4、paritions

这个属性是有关分区表的相关查询操作,还未遇到过占不讨论,遇到了再做补充。

5、type

该属性表示查询计划对某个表的查询方式,其有如下取值:

取值说明
system当表的存储引擎为MyISAM、MEMROY并且表中仅有一条记录,那么type的取值就是system
const执行单表查询时,使用主键或者唯一二级索引与常量进行等值匹配查询时,此时type的取值就是const
eq_ref执行连接查询时,被驱动的表使用的是主键或不为null的唯一二级索引进行等值匹配查询时,被驱动表的type的取值就是eq_ref
ref(1)执行单表使用普通的二级索引进行常量等匹配;(2)执行连接查询,被驱动表中的普通二级索引与驱动表的某个列进行等值匹配
fulltext
ref_or_null
index_merge
unique_subquery
index_subquery
range使用索引来进行范围查询
index扫描所有的索引记录
ALL表示全表扫描

(1)system

创建存储引擎为MyISAM的表:

create table table_test(id int) Engine=MyISAM;

执行如下EXPLAIN

explain select * from table_test;

当表中没有数据时的执行计划:
在这里插入图片描述
当表中插入一条记录时type的取值为system,执行计划如下:
在这里插入图片描述
当表中插入多条记录时type的取值为ALL,执行计划如下:
在这里插入图片描述

(2)const

对于单表的查询使用主键与常量进行等值匹配筛选,此时的type的取值就是const

explain select * from source_learn where id = 1;

在这里插入图片描述

(3)eq_ref

下面执行的查询语句,被驱动表使用的是主键进行等值匹配查询,此时被驱动表的type取值就是eq_ref。

explain select * from source_learn_param inner join source_learn on source_learn.id = source_learn_param.source_id;

在这里插入图片描述

(4)ref

执行单表使用普通的二级索引进行常量等匹配,此时type的取值为ref

explain select * from source_learn_param where source_id = 1;

在这里插入图片描述
执行连接查询,被驱动表中的普通二级索引与驱动表的某个列进行等值匹配,此时type的取值为ref

explain select * from source_learn inner join source_learn_param on source_learn_param.source_id = source_learn.id;

在这里插入图片描述

(5)fulltext

暂时没碰到过,碰到了在做补充说明。

(6)ref_or_null

(7)index_merge

(8)unique_subquery

(9)index_subquery

(10)range

下面的查询语句使用了普通索引来进行范围查询,type的取值为range

explain select * from source_learn_param where source_id > 3;

在这里插入图片描述

explain select * from source_learn_param where id > 3;

在这里插入图片描述

(11)index

EXPLAIN select source_learn.data_type, (select DISTINCT(source_id) from source_learn_param where source_learn_param.data_type = source_learn.data_type) as key_source_id from source_learn;

在这里插入图片描述

6、possible_keys

对某查询语句进行查询时可能使用到那些索引

7、key

对于某查询语句实际上使用到的索引

8、key_len

9、ref

显示了在key列记录的索引中,表查找值所用到的列或常量

10、rows

扫描出的行数,这个是个估算的值,并不是真正的结果集

11、filtered

filtered表示返回结果的行数占需读取行数的百分比,filtered列的值依赖于统计信息。

12、Extra

  • 14
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玉成226

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值