EXPLAIN簡介
當我們需要優化一個SQL語句的時候,我們需要知道該SQL的執行計划,比如是全表掃描,還是索引掃描;在MySQL中我們可以通過EXPLAIN去完成,EXPLAIN命令是查看優化器如何決定執行查詢的主要方法。可以幫助我們深入了解MySQL的基於開銷的優化器,還可以獲得很多可能被優化器考慮到的訪問策略的細節,以及當運行SQL語句時哪種策略預計會被優化器采用。
在select 語句之前增加 explain 關鍵字,MySQL 會在查詢上設置一個標記,執行查詢時,會返回執行計划的信息,而不是執行這條SQL(如果 from 中包含子查詢,仍會執行該子查詢,將結果放入臨時表中)。
執行計划各字段含義
EXPLAIN輸出字段包含id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra幾項信息。
一、ID
ID是用來順序標識整個查詢中SELELCT 語句的,在嵌套查詢中id越大的語句越先執行。該值可能為NULL,如果這一行用來說明的是其他行的聯合結果。
ID列的值越大,執行優先級越高,id相同則從上往下執行,id值如果為NULL則最后執行。
二、SELECT_TYPE
select_type表示對應行的查詢類型是簡單查詢還是復雜的查詢,分為以下幾類:
1、simple:表示簡單子查詢,不包含子查詢和union;
2、primary:表示復雜查詢中最外層的 select;
3、subquery:一般子查詢中的子查詢被標記為subquery,也就是位於select列表中的查詢;
4、derived:包含在 from 子句中的子查詢。MySQL會將結果存放在一個臨時表中,也稱為派生表;
5、union:位於union中第二個及其以后的子查詢被標記為union,第一個就被標記為primary如果是union位於from中則標記為derived;
三、TABLE
TABLE表示對應行正在訪問哪一個表,表名或者別名;
- 關聯優化器會為查詢選擇關聯順序,左側深度優先;
- 當from中有子查詢的時候,表名是derivedN的形式,N指向子查詢,也就是explain結果中的下一列;
- 當有union result的時候,表名是union 1,2等的形式,1,2表示參與union的query id;
MySQL對待這些表和普通表一樣,但是這些“臨時表”是沒有任何索引的。
四、TYPE
type顯示的是訪問類型,是較為重要的一個指標,結果值從好到壞依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL ,一般來說,得保證查詢至少達到range級別,最好能達到ref;
type也可能出現NULL值,NULL值是mysql能夠在優化階段分解查詢語句,在執行階段用不着再訪問表或索引。例如:在索引列中選取最小值,可以單獨查找索引來完成,不需要在執行時訪問表。
1、system:只有一條數據的系統表,或派生表只有一條數據的子查詢;
2、const:當確定最多只會有一行匹配的時候,MySQL優化器會在查詢前讀取它而且只讀取一次,因此非常快。當主鍵放入where子句時,mysql把這個查詢轉為一個常量(高效);
3、eq_ref:唯一性索引,對於每個鍵的查詢,最多只返回一條符合條件的記錄。使用唯一性索引或主鍵查找時會發生 (高效);
4、ref:非唯一性索引,對於每個索引鍵的查詢,返回匹配所有行(0,多);
5、range:檢索指定范圍的行,key 列顯示使用了哪個索引,where后面是一個范圍查詢(between,>,<,>=,in有時候會失效,從而轉為無索引ALL);
6、index:和全表掃描一樣。只是掃描表的時候按照索引次序進行而不是行。主要優點就是避免了排序, 但是開銷仍然非常大。如在Extra列看到Using index,說明正在使用覆蓋索引,只掃描索引的數據,它比按索引次序全表掃描的開銷要小很多;
7、all:最壞的情況,全表掃描;
五、POSSIBLE_KEYS
顯示查詢有可能會使用到哪些索引,表示該索引可以進行高效地查找,但是列出來的索引對於后續優化過程可能是沒有用的,只是一種預測;
六、KEY
key列顯示MySQL實際決定使用的鍵(索引)。如果沒有選擇索引,鍵是NULL。要想強制MySQL使用或忽視possible_keys列中的索引,在查詢中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。
七:KEY_LEN
key_len列顯示MySQL決定使用的鍵長度。如果鍵是NULL,則長度為NULL。使用的索引的長度。在不損失精確性的情況下,長度越短越好。
八、REF
ref列顯示使用哪個列或常數與key一起從表中選擇行。
九、ROWS
rows列顯示MySQL認為它執行查詢時必須檢查的行數。注意這是一個預估值。
十、EXTRA
Extra是EXPLAIN輸出中另外一個很重要的列,該列顯示MySQL在查詢過程中的一些詳細信息,MySQL查詢優化器執行查詢的過程中對查詢計划的重要補充信息。
1、Using filesort:說明mysql會對數據使用一個外部的索引排序,而不是按照表內的索引順序進行讀取。MySQL中無法利用索引完成的排序操作稱為“文件排序;
2、Using temporary:用臨時表保存中間結果,常用於GROUP BY 和 ORDER BY操作中,一般看到它說明查詢需要優化了,就算避免不了臨時表的使用也要盡量避免硬盤臨時表的使用;
3、Not exists:MYSQL優化了LEFT JOIN,一旦它找到了匹配LEFT JOIN標准的行,就不再搜索了;
4、Using index: 說明查詢是覆蓋了索引的,不需要讀取數據文件,從索引樹(索引文件)中即可獲得信息。如果同時出現using where,表明索引被用來執行索引鍵值的查找,沒有using where,表明索引用來讀取數據而非執行查找動作。這是MySQL服務層完成的,但無需再回表查詢記錄;
5、Using index condition: MySQL 5.6加入的新特性,。簡單說一點就是MySQL原來在索引上是不能執行如like這樣的操作的,但是現在可以了,這樣減少了不必要的IO操作,但是只能用在二級索引上;
6、Using where: 表明使用了where 過濾。注意:Extra列出現Using where表示MySQL服務器將存儲引擎返回服務層以后再應用WHERE條件過濾;
7、Using join buffer: 表示使用了連接緩存;
8、impossible where: where子句的值總是false,不能選擇任何行;
9、select tables optimized away:在沒有GROUP BY子句的情況下,基於索引優化MIN/MAX操作,或者對於MyISAM存儲引擎優化COUNT(*)操作,不必等到執行階段再進行計算,查詢執行計划生成的階段即完成優化;
10、Distinct:優化distinct操作,在找到第一匹配的行后它將停止找更多的行;
本文根據平時使用並結合其他資料整理以作為筆記備忘,文中如有存在描述不正確,歡迎指正、補充!!!