explain學習---各字段含義

explain學習---各字段含義

所有字段

 

1、id


SELECT查詢的序列號,包含一組數字,表示查詢中執行SELECT語句或操作表的順序包含三種情況:
    1.id相同,執行順序由上至下
    2.id不同,如果是子查詢,id序號會遞增,id值越大優先級越高,越先被執行
    3.id既有相同的,又有不同的。id如果相同認爲是一組,執行順序由上至下; 在所有組中,id值越大優先級越高,越先執       行。


2、select_type


SIMPLE:簡單SELECT查詢,查詢中不包含子查詢或者UNION
PRIMARY:查詢中包含任何複雜的子部分,最外層的查詢(外層)
SUBQUERY:SELECT或WHERE中包含的子查詢部分(內層)

DERIVED:在FROM中包含的子查詢被標記爲DERIVER(衍生), MySQL會遞歸執行這些子查詢,把結果放到臨時表中(除非不得已,不建議使用)
UNION:若第二個SELECT出現UNION,則被標記爲UNION, 若UNION包含在FROM子句的子查詢中,外層子查詢將被標記爲DERIVED
UNION RESULT:合併的結果


3、table


表名(別名)


4、type  


type顯示的是訪問類型,是較爲重要的一個指標,結果值從最好到最壞依次是:
system>const>eq_ref>ref>fulltext>ref_or_null>index_merge>unique_subquery>index_subquery>range>index>ALL(詳細)

system > const  > eq_ref > ref > range > index > all(總體)
一般來說,得保證查詢至少達到range級別,最好能達到ref。

system:表只有一行記錄(等於系統表),這是const類型的特例,平時不會出現
const:如果通過索引依次就找到了,const用於比較主鍵索引或者unique索引。 因爲只能匹配一行數據,所以很快。如果將主鍵置於where列表中,MySQL就能將該查詢轉換爲一個常量
eq_ref:唯一性索引掃描,對於每個索引鍵,表中只有一條記錄與之匹配。常見於主鍵或唯一索引掃描
ref:非唯一性索引掃描,返回匹配某個單獨值的所有行。本質上也是一種索引訪問,它返回所有匹配 某個單獨值的行,然而它可能會找到多個符合條件的行,所以它應該屬於查找和掃描的混合體
range:只檢索給定範圍的行,使用一個索引來選擇行。簡單的說就是給定了範圍between、<、>、in等同時還使用了索引
index:Full Index Scan ,index與ALL的區別爲index類型只遍歷索引樹,這通常比ALL快,因爲索引文件通常比數據文件小。 (也就是說雖然ALL和index都是讀全表, 但index是從索引中讀取的,而ALL是從硬盤讀取的)
all:Full Table Scan,遍歷全表獲得匹配的行

5、possible_keys


顯示可能應用在這張表中的索引,一個或多個。 查詢涉及到的字段上若存在索引,則該索引將被列出,但不一定被查詢實際使用


6、key


實際使用的索引。如果爲NULL,則沒有使用索引。 查詢中若出現了覆蓋索引,則該索引僅出現在key列表中。


7、key_len


表示索引中使用的字節數,可通過該列計算查詢中使用的索引的長度。在不損失精度的情況下,長度越短越好。key_len顯示的值爲索引字段的最大可能長度,並非實際使用長度,即key_len是根據表定義計算而得,不是通過表內檢索出的。


8、ref


顯示索引的哪一列被使用了,哪些列或常量被用於查找索引列上的值。


9、rows


根據表統計信息及索引選用情況,大致估算出找到所需記錄多需要讀取的行數。


10、Extra


包含不適合在其他列中顯示但十分重要的額外信息:
1、Using filesort: 說明MySQL會對數據使用一個外部的索引排序,而不是按照表內的索引順序進行讀取。MySQL中無法利用索引完成的排序操作稱爲“文件排序”很危險!!!
2、Using temporary:  使用了臨時表保存中間結果,MySQL在對查詢結果排序時使用臨時表。常見於排序order by和分組查詢group by “很危險!!!
3、Using index: 表示相應的SELECT操作中使用了覆蓋索引(Covering Index),避免訪問了表的數據行,效率不錯。 如果同時出現using where,表明索引被用來執行索引鍵值的查找; 如果沒有同時出現using where,表明索引用來讀取數據而非執行查找動作 覆蓋索引(Covering Index): 理解方式1:SELECT的數據列只需要從索引中就能讀取到,不需要讀取數據行,MySQL可以利用索引返回SELECT列表中 的字段,而不必根據索引再次讀取數據文件,換句話說查詢列要被所建的索引覆蓋 理解方式2:索引是高效找到行的一個方法,但是一般數據庫也能使用索引找到一個列的數據,因此他不必讀取整個行。 畢竟索引葉子節點存儲了他們索引的數據;當能通過讀取索引就可以得到想要的數據,那就不需要讀取行了,一個索引 包含了(覆蓋)滿足查詢結果的數據就叫做覆蓋索引 注意: 如果要使用覆蓋索引,一定要注意SELECT列表中只取出需要的列,不可SELECT *, 因爲如果所有字段一起做索引會導致索引文件過大查詢性能下降
6、impossible where: WHERE子句的值總是false,不能用來獲取任何元組
7、select tables optimized away: 在沒有GROUP BY子句的情況下基於索引優化MIN/MAX操作或者對於MyISAM存儲引擎優化COUNT(*)操作, 不必等到執行階段再進行計算,查詢執行計劃生成的階段即完成優化
8、distinct: 優化distinct操作,在找到第一匹配的元祖後即停止找同樣值的操作

 

總結

 

1. 對需要查詢和排序的字段要加索引。
2. 在一定環境下,left join還是比普通連接查詢效率要高,但是要儘量少地連接表,並且在做連接查詢時注意觀察索引是否起了作用。
3. 排序儘量對第一個表的索引字段進行,可以避免mysql創建臨時表,這是非常耗資源的。
4. 對where條件裏涉及到的字段,應適當地添加索引,這樣會對排序操作有優化的作用。
5. 在做隨機抽取數據的需求時,避免使用order by rand(),從上面的例子可以看出,這種是很浪費數據庫資源的,在執行過程中用show processlist查看,會發現第(3)條有Copying to tmp table on disk。而對(3)和(4)的對比得知,如果要實現這個功能,最好另闢奚徑,來減輕Mysql的壓力。
6. 從第4點可以看出,如果說在分頁時我們能先得到主鍵,再根據主鍵查詢相關內容,也能得到查詢的優化效果。通過國外《High Performance MySQL》專家組的測試可以看出,根據主鍵進行查詢的類似“SELECT ... FROM... WHERE id = ...”的SQL語句(其中id爲PRIMARYKEY),每秒鐘能夠處理10000次 以上的查詢,而普通的SELECT查詢每秒只能處理幾十次到幾百次 。涉及到分頁的查詢效率問題,網上的可用資源越來越多,查詢功能也體現出了它的重要性。也便是sphinx、lucene這些第三方搜索引擎的用武之地了。
7. 在平時的作業中,可以打開Mysql的Slow queries功能,經常檢查一下是哪些語句降低的Mysql的執行效率,並進行定期優化。

 

詳細內容可以參考下節mysql優化建議

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