EXPLAIN 命令詳解

在工做中,咱們用於捕捉性能問題最經常使用的就是打開慢查詢,定位執行效率差的SQL,那麼當咱們定位到一個SQL之後還不算完事,咱們還須要知道該SQL的執行計劃,好比是全表掃描,仍是索引掃描,這些都須要經過EXPLAIN去完成。EXPLAIN命令是查看優化器如何決定執行查詢的主要方法。能夠幫助咱們深刻了解MySQL的基於開銷的優化器,還能夠得到不少可能被優化器考慮到的訪問策略的細節,以及當運行SQL語句時哪一種策略預計會被優化器採用。須要注意的是,生成的QEP並不肯定,它可能會根據不少因素髮生改變。MySQL不會將一個QEP和某個給定查詢綁定,QEP將由SQL語句每次執行時的實際狀況肯定,即使使用存儲過程也是如此。儘管在存儲過程當中SQL語句都是預先解析過的,但QEP仍然會在每次調用存儲過程的時候才被肯定。mysql

經過執行計劃能夠知道什麼?sql

(root@yayun-mysql-server) [test]>explain select d1.age, t2.id from (select age,name from t1 where id in (1,2))d1, t2 where d1.age=t2.age group by d1.age, t2.id order by t2.id;
+----+-------------+------------+-------+---------------+---------+---------+--------+------+---------------------------------+
| id | select_type | table      | type  | possible_keys | key     | key_len | ref    | rows | Extra                           |
+----+-------------+------------+-------+---------------+---------+---------+--------+------+---------------------------------+
|  1 | PRIMARY     | <derived2> | ALL   | NULL          | NULL    | NULL    | NULL   |    2 | Using temporary; Using filesort |
|  1 | PRIMARY     | t2         | ref   | age           | age     | 5       | d1.age |    1 | Using where; Using index        |
|  2 | DERIVED     | t1         | range | PRIMARY       | PRIMARY | 4       | NULL   |    2 | Using where                     |
+----+-------------+------------+-------+---------------+---------+---------+--------+------+---------------------------------+
3 rows in set (0.00 sec)

(root@yayun-mysql-server) [test]>

MySQL執行計劃調用方式
1.EXPLAIN SELECT ……
變體:
2.EXPLAIN EXTENDED SELECT ……
將執行計劃"反編譯"成SELECT語句,運行SHOW WARNINGS
可獲得被MySQL優化器優化後的查詢語句
3.EXPLAIN PARTITIONS SELECT ……
用於分區表的EXPLAIN生成QEP的信息緩存

執行計劃包含的信息服務器

+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+

1. id:函數

包含一組數字,表示查詢中執行select子句或操做表的順序性能

Example(id相同,執行順序由上至下優化

(root@yayun-mysql-server) [test]>explain select t2.* from t1, t2, t3 where t1.id=t2.id and t1.id=t3.id and t1.name='';
+----+-------------+-------+--------+---------------+---------+---------+------------+------+--------------------------+
| id | select_type | table | type   | possible_keys | key     | key_len | ref        | rows | Extra                    |
+----+-------------+-------+--------+---------------+---------+---------+------------+------+--------------------------+
|  1 | SIMPLE      | t1    | ref    | PRIMARY,name  | name    | 63      | const      |    1 | Using where; Using index |
|  1 | SIMPLE      | t2    | eq_ref | PRIMARY       | PRIMARY | 4       | test.t1.id |    1 |                          |
|  1 | SIMPLE      | t3    | eq_ref | PRIMARY       | PRIMARY | 4       | test.t1.id |    1 | Using index              |
+----+-------------+-------+--------+---------------+---------+---------+------------+------+--------------------------+
3 rows in set (0.00 sec)

(root@yayun-mysql-server) [test]>

Example (若是是子查詢,id的序號會遞增,id值越大優先級越高,越先被執行)spa

(root@yayun-mysql-server) [test]>explain select t2.* from t2 where id = (select id from t1 where id = (select t3.id from t3 where t3.name=''));
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                                               |
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
|  1 | PRIMARY     | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Impossible WHERE noticed after reading const tables |
|  2 | SUBQUERY    | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | no matching row in const table                      |
|  3 | SUBQUERY    | t3    | ref  | name          | name | 63      |      |    1 | Using where; Using index                            |
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
3 rows in set (0.00 sec)

(root@yayun-mysql-server) [test]>

Example(id若是相同,能夠認爲是一組,從上往下順序執行;在全部組中,id值越大,優先級越高,越先執行)code

(root@yayun-mysql-server) [test]>explain select t2.* from (select t3.id from t3 where t3.name='')s1, t2 where s1.id=t2.id;
+----+-------------+------------+--------+---------------+---------+---------+-------+------+--------------------------+
| id | select_type | table      | type   | possible_keys | key     | key_len | ref   | rows | Extra                    |
+----+-------------+------------+--------+---------------+---------+---------+-------+------+--------------------------+
|  1 | PRIMARY     | <derived2> | system | NULL          | NULL    | NULL    | NULL  |    1 |                          |
|  1 | PRIMARY     | t2         | const  | PRIMARY       | PRIMARY | 4       | const |    1 |                          |
|  2 | DERIVED     | t3         | ref    | name          | name    | 63      |       |    1 | Using where; Using index |
+----+-------------+------------+--------+---------------+---------+---------+-------+------+--------------------------+
3 rows in set (0.00 sec)

(root@yayun-mysql-server) [test]>

2. select_typeserver

示查詢中每一個select子句的類型(簡單OR複雜)

a. SIMPLE:查詢中不包含子查詢或者UNION
b. 查詢中若包含任何複雜的子部分,最外層查詢則被標記爲:PRIMARY
c. 在SELECT或WHERE列表中包含了子查詢,該子查詢被標記爲:SUBQUERY
d. 在FROM列表中包含的子查詢被標記爲:DERIVED(衍生)用來表示包含在from子句中的子查詢的select,mysql會遞歸執行並將結果放到一個臨時表中。服務器內部稱爲"派生表",由於該臨時表是從子查詢中派生出來的
e. 若第二個SELECT出如今UNION以後,則被標記爲UNION;若UNION包含在FROM子句的子查詢中,外層SELECT將被標記爲:DERIVED
f. 從UNION表獲取結果的SELECT被標記爲:UNION RESULT

SUBQUERY和UNION還能夠被標記爲DEPENDENT和UNCACHEABLE。
DEPENDENT意味着select依賴於外層查詢中發現的數據。
UNCACHEABLE意味着select中的某些 特性阻止結果被緩存於一個item_cache中。

Example

(root@yayun-mysql-server) [test]>explain select d1.name, ( select id from t3) d2 from (select id,name from t1 where name='')d1 union (select name,id from t2);
+----+--------------+------------+--------+---------------+------+---------+------+------+--------------------------+
| id | select_type  | table      | type   | possible_keys | key  | key_len | ref  | rows | Extra                    |
+----+--------------+------------+--------+---------------+------+---------+------+------+--------------------------+
|  1 | PRIMARY      | <derived3> | system | NULL          | NULL | NULL    | NULL |    0 | const row not found      |
|  3 | DERIVED      | t1         | ref    | name          | name | 63      |      |    1 | Using where; Using index |
|  2 | SUBQUERY     | t3         | index  | NULL          | age  | 5       | NULL |    6 | Using index              |
|  4 | UNION        | t2         | index  | NULL          | name | 63      | NULL |    4 | Using index              |
| NULL | UNION RESULT | <union1,4> | ALL    | NULL          | NULL | NULL    | NULL | NULL |                          |
+----+--------------+------------+--------+---------------+------+---------+------+------+--------------------------+
5 rows in set (0.00 sec)

(root@yayun-mysql-server) [test]>

第一行:id列爲1,表示第一個select,select_type列的primary表 示該查詢爲外層查詢,table列被標記爲<derived3>,表示查詢結果來自一個衍生表,其中3表明該查詢衍生自第三個select查詢,即id爲3的select。
第二行:id爲3,表示該查詢的執行次序爲2( 4 => 3),是整個查詢中第三個select的一部分。因查詢包含在from中,因此爲derived。
第三行:select列表中的子查詢,select_type爲subquery,爲整個查詢中的第二個select。
第四行:select_type爲union,說明第四個select是union裏的第二個select,最早執行。
第五行:表明從union的臨時表中讀取行的階段,table列的<union1,4>表示用第一個和第四個select的結果進行union操做。

3. type                                       

表示MySQL在表中找到所需行的方式,又稱「訪問類型」,常見類型以下:

 ALL, index,  range, ref, eq_ref, const, system, NULL

從左到右,性能從最差到最好

Example

a. ALL:Full Table Scan, MySQL將遍歷全表以找到匹配的行

(root@yayun-mysql-server) [test]>explain select * from t1 where email='';
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)

(root@yayun-mysql-server) [test]>

b. index:Full Index Scan,index與ALL區別爲index類型只遍歷索引樹

(root@yayun-mysql-server) [test]>explain select id from t1;
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | index | NULL          | age  | 5       | NULL |    4 | Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)

(root@yayun-mysql-server) [test]>

c. range:索引範圍掃描,對索引的掃描開始於某一點,返回匹配值域的行。顯而易見的索引範圍掃描是帶有between或者where子句裏帶有<, >查詢。當mysql使用索引去查找一系列值時,例如IN()和OR列表,也會顯示range(範圍掃描),固然性能上面是有差別的。

(root@yayun-mysql-server) [test]>explain select * from t1 where id in (1,4);
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | range | PRIMARY       | PRIMARY | 4       | NULL |    2 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)

(root@yayun-mysql-server) [test]>explain select * from t1 where id between 1 and 4;
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | range | PRIMARY       | PRIMARY | 4       | NULL |    3 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)

(root@yayun-mysql-server) [test]>explain select * from t1 where id=1 or id=4;       
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | range | PRIMARY       | PRIMARY | 4       | NULL |    2 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.01 sec)

(root@yayun-mysql-server) [test]>explain select * from t1 where id > 1;      
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | range | PRIMARY       | PRIMARY | 4       | NULL |    3 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)

(root@yayun-mysql-server) [test]>

d. ref:使用非惟一索引掃描或者惟一索引的前綴掃描,返回匹配某個單獨值的記錄行

(root@yayun-mysql-server) [test]>explain select * from t1 where name='yayun';
+----+-------------+-------+------+---------------+------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref   | rows | Extra       |
+----+-------------+-------+------+---------------+------+---------+-------+------+-------------+
|  1 | SIMPLE      | t1    | ref  | name          | name | 63      | const |    1 | Using where |
+----+-------------+-------+------+---------------+------+---------+-------+------+-------------+
1 row in set (0.00 sec)

(root@yayun-mysql-server) [test]>

e. eq_ref:相似ref,區別就在使用的索引是惟一索引,對於每一個索引鍵值,表中只有一條記錄匹配,簡單來講,就是多表鏈接中使用primary key或者 unique key做爲關聯條件

(root@yayun-mysql-server) [test]>explain select t1.name from t1, t2 where t1.id=t2.id;
+----+-------------+-------+--------+---------------+---------+---------+------------+------+-------------+
| id | select_type | table | type   | possible_keys | key     | key_len | ref        | rows | Extra       |
+----+-------------+-------+--------+---------------+---------+---------+------------+------+-------------+
|  1 | SIMPLE      | t1    | index  | PRIMARY       | name    | 63      | NULL       |    4 | Using index |
|  1 | SIMPLE      | t2    | eq_ref | PRIMARY       | PRIMARY | 4       | test.t1.id |    1 | Using index |
+----+-------------+-------+--------+---------------+---------+---------+------------+------+-------------+
2 rows in set (0.00 sec)

(root@yayun-mysql-server) [test]>

f. const、system:當MySQL對查詢某部分進行優化,並轉換爲一個常量時,使用這些類型訪問。如將主鍵置於where列表中,MySQL就能將該查詢轉換爲一個常量

(root@yayun-mysql-server) [test]>explain select * from ( select * from t1 where id=1)b1;
+----+-------------+------------+--------+---------------+---------+---------+------+------+-------+
| id | select_type | table      | type   | possible_keys | key     | key_len | ref  | rows | Extra |
+----+-------------+------------+--------+---------------+---------+---------+------+------+-------+
|  1 | PRIMARY     | <derived2> | system | NULL          | NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | t1         | const  | PRIMARY       | PRIMARY | 4       |      |    1 |       |
+----+-------------+------------+--------+---------------+---------+---------+------+------+-------+
2 rows in set (0.00 sec)

(root@yayun-mysql-server) [test]>

注:system是const類型的特例,當查詢的表只有一行的狀況下,使用system

g. NULL:MySQL在優化過程當中分解語句,執行時甚至不用訪問表或索引,例如從一個索引列裏選取最小值能夠經過單獨索引查找完成。

(root@yayun-mysql-server) [test]>explain select * from t1 where id = (select min(id) from t2);
+----+-------------+-------+-------+---------------+---------+---------+-------+------+------------------------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref   | rows | Extra                        |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+------------------------------+
|  1 | PRIMARY     | t1    | const | PRIMARY       | PRIMARY | 4       | const |    1 |                              |
|  2 | SUBQUERY    | NULL  | NULL  | NULL          | NULL    | NULL    | NULL  | NULL | Select tables optimized away |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+------------------------------+
2 rows in set (0.00 sec)

(root@yayun-mysql-server) [test]>

4. possible_keys
指出MySQL能使用哪一個索引在表中找到記錄,查詢涉及到的字段上若存在索引,則該索引將被列出,但不必定被查詢使用


5. key
顯示MySQL在查詢中實際使用的索引,若沒有使用索引,顯示爲NULL

Example

(root@yayun-mysql-server) [test]>explain select id,age from t1;
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | index | NULL          | age  | 5       | NULL |    4 | Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)

(root@yayun-mysql-server) [test]>

6. key_len
表示索引中使用的字節數,可經過該列計算查詢中使用的索引的長度(key_len顯示的值爲索引字段的最大可能長度,並不是實際使用長度,即key_len是根據表定義計算而得,不是經過表內檢索出的)

7. ref
表示上述表的鏈接匹配條件,即哪些列或常量被用於查找索引列上的值

8. rows
表示MySQL根據表統計信息及索引選用狀況,估算的找到所需的記錄所需
要讀取的行數

Example

(root@yayun-mysql-server) [test]>explain select * from t1 , t2 where t1.id=t2.id and t2.name='atlas';
+----+-------------+-------+--------+---------------+---------+---------+------------+------+-------------+
| id | select_type | table | type   | possible_keys | key     | key_len | ref        | rows | Extra       |
+----+-------------+-------+--------+---------------+---------+---------+------------+------+-------------+
|  1 | SIMPLE      | t2    | ref    | PRIMARY,name  | name    | 63      | const      |    1 | Using where |
|  1 | SIMPLE      | t1    | eq_ref | PRIMARY       | PRIMARY | 4       | test.t2.id |    1 |             |
+----+-------------+-------+--------+---------------+---------+---------+------------+------+-------------+
2 rows in set (0.00 sec)

(root@yayun-mysql-server) [test]>

9. Extra
包含不適合在其餘列中顯示但十分重要的額外信息
a. Using index
該值表示相應的select操做中使用了覆蓋索引(Covering Index)

Example

(root@yayun-mysql-server) [test]>explain select id from t1;
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | index | NULL          | age  | 5       | NULL |    4 | Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)

(root@yayun-mysql-server) [test]>

覆蓋索引(Covering Index)
MySQL能夠利用索引返回select列表中的字段,而沒必要根據索引再次讀取數據文件
包含全部知足查詢須要的數據的索引稱爲覆蓋索引(Covering Index)
注意:若是要使用覆蓋索引,必定要注意select列表中只取出須要的列,不可select *,由於若是將全部字段一塊兒作索引會致使索引文件過大,查詢性能降低

b. Using where
表示mysql服務器將在存儲引擎檢索行後再進行過濾。許多where條件裏涉及索引中的列,當(而且若是)它讀取索引時,就能被存儲引擎檢驗,所以不是全部帶where字句的查詢都會顯示"Using where"。有時"Using where"的出現就是一個暗示:查詢可受益與不一樣的索引。

Example

(root@yayun-mysql-server) [test]>explain select id,name from t1 where id<4;
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra                    |
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
|  1 | SIMPLE      | t1    | index | PRIMARY       | name | 63      | NULL |    4 | Using where; Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
1 row in set (0.00 sec)

(root@yayun-mysql-server) [test]>

c. Using temporary
表示MySQL須要使用臨時表來存儲結果集,常見於排序和分組查詢

這個值表示使用了內部臨時(基於內存的)表。一個查詢可能用到多個臨時表。有不少緣由都會致使MySQL在執行查詢期間建立臨時表。兩個常見的緣由是在來自不一樣表的上使用了DISTINCT,或者使用了不一樣的ORDER BY和GROUP BY列。能夠強制指定一個臨時表使用基於磁盤的MyISAM存儲引擎。這樣作的緣由主要有兩個:
1)內部臨時表佔用的空間超過min(tmp_table_size,max_heap_table_size)系統變量的限制
2)使用了TEXT/BLOB 列

Example

(root@yayun-mysql-server) [test]>explain select id from t1 where id in (1,2) group by age,name;
+----+-------------+-------+-------+---------------+---------+---------+------+------+----------------------------------------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra                                        |
+----+-------------+-------+-------+---------------+---------+---------+------+------+----------------------------------------------+
|  1 | SIMPLE      | t1    | range | PRIMARY       | PRIMARY | 4       | NULL |    2 | Using where; Using temporary; Using filesort |
+----+-------------+-------+-------+---------------+---------+---------+------+------+----------------------------------------------+
1 row in set (0.00 sec)

(root@yayun-mysql-server) [test]>

d. Using filesort
MySQL中沒法利用索引完成的排序操做稱爲「文件排序」

Example

(root@yayun-mysql-server) [test]>explain select id,age from t1 order by name; 
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra          |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
|  1 | SIMPLE      | t1    | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
1 row in set (0.00 sec)

(root@yayun-mysql-server) [test]>explain select id,age from t1 order by age; 
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | index | NULL          | age  | 5       | NULL |    4 | Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)

(root@yayun-mysql-server) [test]>

e. Using join buffer
改值強調了在獲取鏈接條件時沒有使用索引,而且須要鏈接緩衝區來存儲中間結果。若是出現了這個值,那應該注意,根據查詢的具體狀況可能須要添加索引來改進能。

Example

(root@yayun-mysql-server) [test]>explain select t1.name from t1 inner join t2 on t1.name=t2.name;
+----+-------------+-------+-------+---------------+------+---------+--------------+------+--------------------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref          | rows | Extra                    |
+----+-------------+-------+-------+---------------+------+---------+--------------+------+--------------------------+
|  1 | SIMPLE      | t1    | index | name          | name | 63      | NULL         |    4 | Using index              |
|  1 | SIMPLE      | t2    | ref   | name          | name | 63      | test.t1.name |    2 | Using where; Using index |
+----+-------------+-------+-------+---------------+------+---------+--------------+------+--------------------------+
2 rows in set (0.00 sec)

(root@yayun-mysql-server) [test]>alter table t1 drop key name;                                   
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

(root@yayun-mysql-server) [test]>alter table t2 drop key name; 
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

(root@yayun-mysql-server) [test]>explain select t1.name from t1 inner join t2 on t1.name=t2.name;
+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                          |
+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+
|  1 | SIMPLE      | t1    | ALL  | NULL          | NULL | NULL    | NULL |    4 |                                |
|  1 | SIMPLE      | t2    | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where; Using join buffer |
+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+
2 rows in set (0.00 sec)

(root@yayun-mysql-server) [test]>

f. Impossible where
這個值強調了where語句會致使沒有符合條件的行。

Example

(root@yayun-mysql-server) [test]>EXPLAIN SELECT * FROM t1 WHERE 1=2;
+----+-------------+-------+------+---------------+------+---------+------+------+------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra            |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------+
|  1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Impossible WHERE |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------+
1 row in set (0.00 sec)

(root@yayun-mysql-server) [test]>

h. Select tables optimized away
這個值意味着僅經過使用索引,優化器可能僅從聚合函數結果中返回一行.

Example

(root@yayun-mysql-server) [test]>explain select max(id) from t1;
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                        |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
|  1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Select tables optimized away |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
1 row in set (0.00 sec)

(root@yayun-mysql-server) [test]>

I. Index merges
當MySQL 決定要在一個給定的表上使用超過一個索引的時候,就會出現如下格式中的一個,詳細說明使用的索引以及合併的類型。
Using sort_union(...)
Using union(...)
Using intersect(...)

 

總結:• EXPLAIN不會告訴你關於觸發器、存儲過程的信息或用戶自定義函數對查詢的影響狀況• EXPLAIN不考慮各類Cache• EXPLAIN不能顯示MySQL在執行查詢時所做的優化工做• 部分統計信息是估算的,並不是精確值• EXPALIN只能解釋SELECT操做,其餘操做要重寫爲SELECT後查看執行計劃。

相關文章
相關標籤/搜索