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>中,再從臨時表中讀取結果。