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