美文网首页MySQL
87-实战-MySQL-Explain详解

87-实战-MySQL-Explain详解

作者: 紫荆秋雪_文 | 来源:发表于2023-03-07 13:40 被阅读0次

一、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子句是为了把id1的查询和id2的查询的结果集合并起来并去重,所以在内部创建了一个名为<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

对于包含UNIONUNION 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_typeDEPENDENT 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>,说明该表其实就是id2对应的子查询执行之后产生的物化表,然后将s1该物化表进行连接查询

四、Json格式的执行计划

相关文章

网友评论

    本文标题:87-实战-MySQL-Explain详解

    本文链接:https://www.haomeiwen.com/subject/btrjldtx.html