Mysql-Explain(四):输出列-select_type
Mysql-Explain(一):explain简介和输出列解释
Mysql-Explain(二):explain实验数据准备
Mysql-Explain(三):输出列-id
Mysql-Explain(四):输出列-select_type
Mysql-Explain(五):输出列-type
Mysql-Explain(六):输出列-possiable_keys、key、key_len
Mysql-Explain(七):输出列-ref、rows
Mysql-Explain(八):输出列-extra
简介
select_type | 查询的类型,主要用来区别普通查询,联合查询,子查询等复杂查询 | SIMPLE | 简单的select查询,查询中不包含子查询或者UNION |
PRIMARY | 查询中若包含任何复杂的子部分,最外层的查询则被标记为PRIMARY | ||
SUBQUERY | 在select或者where列表中包含了子查询 | ||
DERIVED | 在from列表中包含的子查询会被标记为DERICED(衍生),Mysql会递归地执行这些子查询,然后把结果放到临时表 | ||
UNION | 若第二个select语句出现在UNION之后,则被标记为UNION。若UNION包含在from子句的子查询中,外层select则被标记为DERIVED | ||
UNION RESULT | 从union表获取结果的select |
演示
-
SIMPLE:简单的select查询,查询中不包含子查询或者UNION
mysql> explain select * from student; +----+-------------+---------+------------+------+---------------+------+---------+------+---------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+---------+------------+------+---------------+------+---------+------+---------+----------+-------+ | 1 | SIMPLE | student | NULL | ALL | NULL | NULL | NULL | NULL | 1994898 | 100.00 | NULL | +----+-------------+---------+------------+------+---------------+------+---------+------+---------+----------+-------+ 1 row in set, 1 warning (0.00 sec) mysql> explain select * from student -> left join school on student.school_id=school.id -> where school.id = 1; +----+-------------+---------+------------+-------+---------------+---------+---------+-------+---------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+---------+------------+-------+---------------+---------+---------+-------+---------+----------+-------------+ | 1 | SIMPLE | school | NULL | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | NULL | | 1 | SIMPLE | student | NULL | ALL | NULL | NULL | NULL | NULL | 1994898 | 10.00 | Using where | +----+-------------+---------+------------+-------+---------------+---------+---------+-------+---------+----------+-------------+ 2 rows in set, 1 warning (0.00 sec)
-
PRIMARY:查询中若包含任何复杂的子部分,最外层的查询则被标记为PRIMARY
mysql> explain -> select * from student -> where student.school_id = (select id from school where id < 2); +----+-------------+---------+------------+-------+---------------+---------+---------+------+---------+----------+--------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+---------+------------+-------+---------------+---------+---------+------+---------+----------+--------------------------+ | 1 | PRIMARY | student | NULL | ALL | NULL | NULL | NULL | NULL | 1994898 | 10.00 | Using where | | 2 | SUBQUERY | school | NULL | range | PRIMARY | PRIMARY | 4 | NULL | 1 | 100.00 | Using where; Using index | +----+-------------+---------+------------+-------+---------------+---------+---------+------+---------+----------+--------------------------+ 2 rows in set, 1 warning (0.00 sec)
上图所示,对表school的查询的select_type是subquery,表示这是个子查询,对表student的查询的select_type是PRIMARY,表示这是主查询。子查询的id为2,大于主查询id,表示先执行了子查询,再执行主查询。
-
SUBQUERY:在select或者where列表中包含了子查询
where列表的子查询如上面PRIMARY例子所示,select列表的子查询如下面所示:mysql> explain -> select student.*,(select name from school where id =1) from student -> where student.school_id = 1; +----+-------------+---------+------------+-------+---------------+---------+---------+-------+---------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+---------+------------+-------+---------------+---------+---------+-------+---------+----------+-------------+ | 1 | PRIMARY | student | NULL | ALL | NULL | NULL | NULL | NULL | 1994898 | 10.00 | Using where | | 2 | SUBQUERY | school | NULL | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | NULL | +----+-------------+---------+------------+-------+---------------+---------+---------+-------+---------+----------+-------------+ 2 rows in set, 1 warning (0.03 sec)
-
DERIVED:在from列表中包含的子查询会被标记为DERICED(衍生),Mysql会递归地执行这些子查询,然后把结果放到临时表
mysql> explain -> select student.*,sc.name from -> (select * from school where school.id < 10 limit 2)sc,student -> where sc.id = student.school_id; +----+-------------+------------+------------+-------+---------------+---------+---------+------+---------+----------+----------------------------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+------------+------------+-------+---------------+---------+---------+------+---------+----------+----------------------------------------------------+ | 1 | PRIMARY | <derived2> | NULL | ALL | NULL | NULL | NULL | NULL | 2 | 100.00 | NULL | | 1 | PRIMARY | student | NULL | ALL | NULL | NULL | NULL | NULL | 1994898 | 10.00 | Using where; Using join buffer (Block Nested Loop) | | 2 | DERIVED | school | NULL | range | PRIMARY | PRIMARY | 4 | NULL | 9 | 100.00 | Using where | +----+-------------+------------+------------+-------+---------------+---------+---------+------+---------+----------+----------------------------------------------------+ 3 rows in set, 1 warning (0.00 sec)
explain返回的第三行记录中,select_type=DERIVED,表示对school的查询结果会派生出新的临时表,这张临时表就是第一行记录中显示的<derived2>。
-
UNION:若第二个select语句出现在UNION之后,则被标记为UNION。若UNION包含在from子句的子查询中,外层select则被标记为DERIVED
mysql> explain -> select student.*,school.name as school_name from student left join school on student.school_id=school.id where school.name is null -> union -> select student.*,major.name as major_name from student left join major on student.major_id=major.id where major.name is null; +----+--------------+------------+------------+--------+---------------+---------+---------+------------------------+---------+----------+-----------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+--------------+------------+------------+--------+---------------+---------+---------+------------------------+---------+----------+-----------------+ | 1 | PRIMARY | student | NULL | ALL | NULL | NULL | NULL | NULL | 1994898 | 100.00 | NULL | | 1 | PRIMARY | school | NULL | eq_ref | PRIMARY | PRIMARY | 4 | mydb.student.school_id | 1 | 10.00 | Using where | | 2 | UNION | student | NULL | ALL | NULL | NULL | NULL | NULL | 1994898 | 100.00 | NULL | | 2 | UNION | major | NULL | eq_ref | PRIMARY | PRIMARY | 4 | mydb.student.major_id | 1 | 10.00 | Using where | | NULL | UNION RESULT | <union1,2> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary | +----+--------------+------------+------------+--------+---------------+---------+---------+------------------------+---------+----------+-----------------+ 5 rows in set, 1 warning (0.02 sec)
从上面返回的结果中可以看出,对student和major的联合查询被标记为了UNION,并且在Id上也被标记为同一组。
-
UNION RESULT:从union表获取结果的select
还是回到上面UNION的例子中去,第五行记录所示,union上下的查询语句会把结果合并到临时表<union1,2>中,再从临时表中读取结果。