一、EXPLAIN信息
EXPLAIN信息.png
二、数据准备-表 single_table
三、EXPLAIN字段说明
3.1、id
查询语句中每出现一个
SELECT关键字,设计MySQL的大佬就会为它分配一个唯一的id值
3.1.1、多表连接
对于
连接查询来说,一个SELECT关键字后边的FROM子句中可以跟随多个表,所以在连接查询的执行计划中,每个表都会对应一条记录,但是这些记录的id值都是相同的
- SQL
EXPLAIN
SELECT *
FROM single_table s1
INNER JOIN single_table2 s2;
-
EXPLAIN结果
EXPLAIN-多表连接-但是id相同.png
-
小结
在连接查询的执行计划中,每个表都会对应一条记录,这些记录的id列的值是相同的,出现在前面的表表示驱动表,出现在后边的表表示被驱动表。所以从上面的EXPLAIN输出中我们可以看出,查询优化器准备让s1表作为驱动表,让s2表作为被驱动表来执行查询
3.1.2、子查询可以有 多个id值
- SQL
DESC
SELECT *
FROM single_table s1
WHERE s1.key1 IN (SELECT s2.key2 FROM single_table2 s2)
OR s1.key3 = 'a';
-
EXPLAIN
image.png
3.1.3、包含UNION子句的查询
-
UNION结果去重
DESC
SELECT *
FROM single_table
UNION
SELECT *
FROM single_table2;
-
EXPLAIN
image.png
-
小结
正如上面的查询计划中所示,
UNION子句是为了把id为1的查询和id为2的查询的结果集合并起来并去重,所以在内部创建了一个名为<union1, 2>的临时表(就是执行计划第三条记录的table列的名称),id为NULL表明这个临时表是为了合并两个查询的结果集而创建的
-
UNION ALL结果不去重
DESC
SELECT *
FROM single_table
UNION ALL
SELECT *
FROM single_table2;
EXPLAIN.png
3.2、select_type
设计MySQL的大佬为每一个
SELECT关键字代表的小查询都定义了一个称之为select_type的属性,意思是我们只要知道了某个小查询的select_type属性,就知道了这个小查询在整个大查询中扮演了一个什么角色
select_type可选值.png
3.2.1、SIMPLE
查询语句中
不包含UNION或者子查询的查询都算作是SIMPLE类型
3.2.2、PRIMARY
对于包含
UNION、UNION ALL或者子查询的大查询来说,它是由几个小查询组成的,其中最左边的那个查询的select_type值就是PRIMARY
- SQL
DESC
SELECT *
FROM single_table
UNION
SELECT *
FROM single_table2;
DESC
SELECT *
FROM single_table
UNION ALL
SELECT *
FROM single_table2;
3.2.3、UNION
对于包含
UNION或者UNION ALL的大查询来说,它是由几个小查询组成的,其中除了最左边的那个小查询以外,其余的小查询的select_type值就是UNION
3.2.4、UNION
MySQL选择使用
临时表来完成UNION查询的去重工作,针对该临时表的查询的select_type就是UNION RESULT
3.2.5、SUBQUERY
包含
子查询的查询语句不能够转为对应的semi-join的形式,并且该子查询是不相关子查询,并且查询优化器决定采用将该子查询物化的方案来执行该子查询时,该子查询的第一个SELECT关键字代表的那个查询的select_type就是SUBQUERY
- SQL
DESC
SELECT *
FROM single_table s1
WHERE s1.key1 IN (SELECT key2 FROM single_table2 s2)
OR s1.key3 > 'a';
- 小结
外层查询的
select_type就是PRIMARY,子查询的select_type就是SUBQUERY。需要大家注意的是,由于select_type为SUBQUERY的子查询由于会被物化,所以只需要执行一遍
3.2.6、DEPENDENT SUBQUERY
包含子查询的查询语句不能够转为对应的
semi-join的形式,并且该子查询是相关子查询,则该子查询的第一个SELECT关键字代表的那个查询的select_type就是DEPENDENT SUBQUERY
- SQL
EXPLAIN
SELECT *
FROM single_table s1
WHERE key1 IN (SELECT key1 FROM single_table2 s2 WHERE s1.key2 = s2.key2)
OR key3 = 'a';
- 小结
select_type为DEPENDENT SUBQUERY的查询可能会被执行多次
3.2.7、DEPENDENT UNION
在包含
UNION或者UNION ALL的大查询中,如果各个小查询都依赖于外层查询的话,那除了最左边的那个小查询之外,其余的小查询的select_type的值就是DEPENDENT UNION
- SQL
EXPLAIN
SELECT *
FROM single_table s1
WHERE key1 IN
(SELECT key1 FROM single_table2 s2 WHERE key1 = 'a' UNION SELECT key1 FROM single_table s3 WHERE key1 = 'b');
- 小结
这个查询比较复杂啊,
大查询里包含了一个子查询,子查询里又是由UNION连起来的两个小查询。从执行计划中可以看出来,SELECT key1 FROM single_table2 s2 WHERE key1 = 'a'这个小查询由于是子查询中第一个查询,所以它的select_type是DEPENDENT SUBQUERY,而SELECT key1 FROM single_table s3 WHERE key1 = 'b'这个查询的select_type就是DEPENDENT UNION
3.2.8、DERIVED
对于采用
物化的方式执行的包含派生表的查询,该派生表对应的子查询的select_type就是DERIVED
- SQL
EXPLAIN
SELECT *
FROM (SELECT key1, COUNT(*) AS c FROM single_table s1 GROUP BY key1) AS derived_s1
WHERE c > 1;
3.2.9、MATERIALIZED
当查询优化器在执行包含
子查询的语句时,选择将子查询物化之后与外层查询进行连接查询时,该子查询对应的select_type属性就是MATERIALIZED
- SQL
EXPLAIN
SELECT *
FROM single_table s1
WHERE key1 IN (SELECT key1 FROM single_table s2);
EXPLAIN.png
- 小结
执行计划的第三条记录的
id值为2,说明该条记录对应的是一个单表查询,从它的select_type值为MATERIALIZED可以看出,查询优化器是要把子查询先转换成物化表。然后看执行计划的前两条记录的id值都为1,说明这两条记录对应的表进行连接查询,需要注意的是第二条记录的table列的值是<subquery2>,说明该表其实就是id为2对应的子查询执行之后产生的物化表,然后将s1和该物化表进行连接查询








网友评论