前文链接 MySQL性能分析工具的使用:EXPLAIN的概述及各列的作用
一条大的查询语句里边可以包含若干个SELECT关键字,每个SELECT关键字代表着一个小的查询语句,而每个SELECT关键字的FROM子句中都可以包含若干张表(这些表用来做连接查询),每一张表都对应着执行计划输出中的一条记录,对于在同一个SELECT:关键字中的表来说,它们的id值是相同的。
MySQL为每一个SELECT关键字代表的小查询都定义了一个称之为select_type的属性,意思是我们只要知道了
某个小查询的select_type属性,就知道了这个小查询在整个大查询中扮演了一个什么角色。
查询语句中不包含 UNION 或者子查询的查询
EXPLAIN SELECT * FROM s1;
当然,连接查询也算是 SIMPLE 类型,比如: EXPLAIN SELECT * FROM s1 INNER JOIN s2;
对于包含 UNION、UNION ALL 或者子查询的大查询来说,它是由几个小查询组成的,其中最左边的那个查询的 select_type 的值就是 PRIMARY ,比方说: EXPLAIN SELECT * FROM s1 UNION SELECT * FROM s2;
从结果中可以看到,最左边的小查询 SELECT * FROM s1 对应的是执行计划中的第一条记录,它 的select_type的值就是 PRIMARY 。
对于包含 UNION 或者 UNION ALL 的大查询来说,它是由几个小查询组成的,其中除了最左边的那 个小查询意外,其余的小查询的 select_type 值就是UNION,可以对比上一个例子的效果。
MySQL 选择使用临时表来完成 UNION 查询的去重工作,针对该临时表的查询的 是UNION RESULT, 例子上边有。
如果包含子查询的查询语句不能够转为对应的 select_type 就 semi-join 的形式,并且该子查询是不相关子查询, 并且查询优化器决定采用将该子查询物化的方案来执行该子查询时,该子查询的第一个 SELECT 关 键字代表的那个查询的 select_type 就是 SUBQUERY ,比如下边这个查询: EXPLAIN SELECT * FROM s1 WHERE key1 IN (SELECT key1 FROM s2) OR key3 = 'a';
子查询的第一个select,并且条件依赖于外部参数EXPLAIN SELECT * FROM s1 WHERE key1 IN (SELECT key1 FROM s2 WHERE s1.key2 = s2.key2) OR key3 = 'a';
EXPLAIN SELECT * FROM (SELECT key1, count(*) as c FROM s1 GROUP BY key1) AS derived_s1 where c > 1;
从执行计划中可以看出,id为2的记录就代表子查询的执行方式,它的select_type是DERIVED, 说明 该子查询是以物化的方式执行的。id为1的记录代表外层查询,大家注意看它的table列显示的是 derived2,表示该查询时针对将派生表物化之后的表进行查询的。
当查询优化器在执行包含子查询的语句时,选择将子查询物化之后的外层查询进行连接查询时,该子查询对应的 select_type 属性就是 MATERIALIZED ,比如下边这个查询: EXPLAIN SELECT * FROM s1 WHERE key1 IN (SELECT key1 FROM s2);
不常用,就不多说了
—— 评论区 ——