MySql中的explain

聲明:本文內容來源網絡,僅供學習參考使用。


mysql> explain select * from user where uname='hurace';
+----+-------------+-------+------+---------------+-------+---------+-------+------+-------------
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+-------+---------+-------+------+-------------
| 1 | SIMPLE | user | ref | idx_3 | idx_3 | 63 | const | 108 | Using index condition |
+----+-------------+-------+------+---------------+-------+---------+-------+------+-------------
各個屬性的含義
id
select查詢的序列號
select_type
select查詢的類型,主要是區別普通查詢和聯合查詢、子查詢之類的複雜查詢。
select類型,它有以下幾種值
2.1 simple 它表示簡單的select,沒有union和子查詢
2.2 primary 最外面的select,在有子查詢的語句中,最外面的select查詢就是primary,上圖中就是這樣
2.3 union union語句的第二個或者說是後面那一個.現執行一條語句,explain 
select * from uchome_space limit 10 union select * from uchome_space limit 10,10
會有如下結果
第二條語句使用了union
2.4 dependent union    UNION中的第二個或後面的SELECT語句,取決於外面的查詢
2.5 union result        UNION的結果,如上面所示
還有幾個參數,這裏就不說了,不重要
table
輸出的行所引用的表。
type
聯合查詢所使用的類型。
type顯示的是訪問類型,是較爲重要的一個指標,結果值從好到壞依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
一般來說,得保證查詢至少達到range級別,最好能達到ref。
這列很重要,顯示了連接使用了哪種類別,有無使用索引.
從最好到最差的連接類型爲const、eq_reg、ref、range、indexhe和ALL

(1).system

這是const聯接類型的一個特例。表僅有一行滿足條件.
2).const

表最多有一個匹配行,它將在查詢開始時被讀取。因爲僅有一行,在這行的列值可被優化器剩餘部分認爲是常數。const表很快,因爲它們只讀取一次!

3). eq_ref

對於每個來自於前面的表的行組合,從該表中讀取一行。這可能是最好的聯接類型,除了const類型。它用在一個索引的所有部分被聯接使用並且索引是UNIQUE或PRIMARY KEY。

eq_ref可以用於使用= 操作符比較的帶索引的列。比較值可以爲常量或一個使用在該表前面所讀取的表的列的表達式。

(4).ref

對於每個來自於前面的表的行組合,所有有匹配索引值的行將從這張表中讀取。如果聯接只使用鍵的最左邊的前綴,或如果鍵不是UNIQUE或PRIMARY KEY(換句話說,如果聯接不能基於關鍵字選擇單個行的話),則使用ref。如果使用的鍵僅僅匹配少量行,該聯接類型是不錯的。

ref可以用於使用=或<=>操作符的帶索引的列。

(5). ref_or_null

該聯接類型如同ref,但是添加了MySQL可以專門搜索包含NULL值的行。在解決子查詢中經常使用該聯接類型的優化。

在下面的例子中,MySQL可以使用ref_or_null聯接來處理ref_tables:

SELECT * FROM ref_table
WHERE key_column=expr OR key_column IS NULL;

(6). index_merge

該聯接類型表示使用了索引合併優化方法。在這種情況下,key列包含了使用的索引的清單,key_len包含了使用的索引的最長的關鍵元素。
例如:
mysql> explain select * from t4 where id=3952602 or accountid=31754306 ;
+----+-------------+-------+-------------+----------------------------+----------------------------+---------+------+------+------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------------+----------------------------+----------------------------+---------+------+------+------------------------------------------------------+
| 1 | SIMPLE | t4 | index_merge | idx_t4_id,idx_t4_accountid | idx_t4_id,idx_t4_accountid | 4,4 | NULL | 2 | Using union(idx_t4_id,idx_t4_accountid); Using where |
+----+-------------+-------+-------------+----------------------------+----------------------------+---------+------+------+------------------------------------------------------+
1 row in set (0.00 sec)

(7). unique_subquery

該類型替換了下面形式的IN子查詢的ref:

value IN (SELECT primary_key FROM single_table WHERE some_expr)
unique_subquery是一個索引查找函數,可以完全替換子查詢,效率更高。

(8).index_subquery

該聯接類型類似於unique_subquery。可以替換IN子查詢,但只適合下列形式的子查詢中的非唯一索引:

value IN (SELECT key_column FROM single_table WHERE some_expr)

(9).range

只檢索給定範圍的行,使用一個索引來選擇行。key列顯示使用了哪個索引。key_len包含所使用索引的最長關鍵元素。在該類型中ref列爲NULL。

當使用=、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN或者IN操作符,用常量比較關鍵字列時,可以使用range

mysql> explain select * from t3 where id=3952602 or id=3952603 ;
+----+-------------+-------+-------+-------------------+-----------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+-------------------+-----------+---------+------+------+-------------+
| 1 | SIMPLE | t3 | range | PRIMARY,idx_t3_id | idx_t3_id | 4 | NULL | 2 | Using where |
+----+-------------+-------+-------+-------------------+-----------+---------+------+------+-------------+
1 row in set (0.02 sec)

(10).index

該聯接類型與ALL相同,除了只有索引樹被掃描。這通常比ALL快,因爲索引文件通常比數據文件小。

當查詢只使用作爲單索引一部分的列時,MySQL可以使用該聯接類型。

(11). ALL

對於每個來自於先前的表的行組合,進行完整的表掃描。如果表是第一個沒標記const的表,這通常不好,並且通常在它情況下很差。通常可以增加更多的索引而不要使用ALL,使得行能基於前面的表中的常數值或列值被檢索出。

possible_keys
指出MySQL能使用哪個索引在該表中找到行。如果是空的,沒有相關的索引。這時要提高性能,可通過檢驗WHERE子句,看是否引用某些字段,或者檢查字段不是適合索引。
key
顯示MySQL實際決定使用的鍵。如果沒有索引被選擇,鍵是NULL。
key_len
顯示MySQL決定使用的鍵長度。如果鍵是NULL,長度就是NULL。文檔提示特別注意這個值可以得出一個多重主鍵裏mysql實際使用了哪一部分。
ref
顯示哪個字段或常數與key一起被使用。
rows
這個數表示mysql要遍歷多少數據才能找到,在innodb上是不準確的。
Extra
如果是Only index,這意味着信息只用索引樹中的信息檢索出的,這比掃描整個表要快。
如果是where used,就是使用上了where限制。
如果是impossible where 表示用不着where,一般就是沒查出來啥。
如果此信息顯示Using filesort或者Using temporary的話會很吃力,WHERE和ORDER BY的索引經常無法兼顧,如果按照WHERE來確定索引,那麼在ORDER BY時,就必然會引起Using filesort,這就要看是先過濾再排序划算,還是先排序再過濾划算。
10.1 Distinct     MySQL發現第1個匹配行後,停止爲當前的行組合搜索更多的行。一直沒見過這個值
10.2 Not exists  
10.3 range checked for each record
沒有找到合適的索引
10.4 using filesort    
MYSQL手冊是這麼解釋的“MySQL需要額外的一次傳遞,以找出如何按排序順序檢索行。通過根據聯接類型瀏覽所有行併爲所有匹配WHERE子句的行保存排序關鍵字和行的指針來完成排序。然後關鍵字被排序,並按排序順序檢索行。”目前不太明白
10.5 using index 只使用索引樹中的信息而不需要進一步搜索讀取實際的行來檢索表中的信息。這個比較容易理解,就是說明是否使用了索引
explain select * from ucspace_uchome where uid = 1的extra爲using index(uid建有索引)
explain select count(*) from uchome_space where groupid=1 的extra爲using where(groupid未建立索引)
10.6 using temporary
爲了解決查詢,MySQL需要創建一個臨時表來容納結果。典型情況如查詢包含可以按不同情況列出列的GROUP BY和ORDER BY子句時。
出現using temporary就說明語句需要優化了
10.7 using where
WHERE子句用於限制哪一個行匹配下一個表或發送到客戶。除非你專門從表中索取或檢查所有行,如果Extra值不爲Using where並且表聯接類型爲ALL或index,查詢可能會有一些錯誤。(這個說明不是很理解,因爲很多很多語句都會有where條件,而type爲all或index只能說明檢索的數據多,並不能說明錯誤,useing where不是很重要,但是很常見)
如果想要使查詢儘可能快,應找出Using filesort 和Using temporary的Extra值。
10.8 Using sort_union(...), Using union(...),Using intersect(...)
這些函數說明如何爲index_merge聯接類型合併索引掃描
10.9 Using index for group-by
類似於訪問表的Using index方式,Using index for group-by表示MySQL發現了一個索引,可以用來查詢GROUP BY或DISTINCT查詢的所有列,而不要額外搜索硬盤訪問實際的表。並且,按最有效的方式使用索引,以便對於每個組,只讀取少量索引條目。



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