MYSQL-EXPLAIN 命令詳解 (轉載)
在工作中,我們用於捕捉性能問題最常用的就是打開慢查詢,定位執行效率差的SQL,那麽當我們定位到一個SQL以後還不算完事,我們還需要知道該SQL的執行計劃,比如是全表掃描,還是索引掃描,這些都需要通過EXPLAIN去完成。EXPLAIN命令是查看優化器如何決定執行查詢的主要方法。可以幫助我們深入了解MySQL的基於開銷的優化器,還可以獲得很多可能被優化器考慮到的訪問策略的細節,以及當運行SQL語句時哪種策略預計會被優化器采用。需要註意的是,生成的QEP並不確定,它可能會根據很多因素發生改變。MySQL不會將一個QEP和某個給定查詢綁定,QEP將由SQL語句每次執行時的實際情況確定,即便使用存儲過程也是如此。盡管在存儲過程中SQL語句都是預先解析過的,但QEP仍然會在每次調用存儲過程的時候才被確定。
通過執行計劃可以知道什麽?
(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值越大優先級越高,越先被執行)
(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值越大,優先級越高,越先執行)
(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_type
示查詢中每個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後查看執行計劃。
MYSQL-EXPLAIN 命令詳解 (轉載)