Mysql-Explain(四):輸出列-select_type

簡介

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章