[MYSQL]-EXPLAIN用法


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表示參與unionquery 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 INDEXUSE INDEX或者IGNORE INDEX

七:KEY_LEN

  key_len列顯示MySQL決定使用的鍵長度。如果鍵是NULL,則長度為NULL。使用的索引的長度。在不損失精確性的情況下,長度越短越好。

八、REF

  ref列顯示使用哪個列或常數與key一起從表中選擇行。

九、ROWS

  rows列顯示MySQL認為它執行查詢時必須檢查的行數。注意這是一個預估值。

十、EXTRA

  ExtraEXPLAIN輸出中另外一個很重要的列,該列顯示MySQL在查詢過程中的一些詳細信息,MySQL查詢優化器執行查詢的過程中對查詢計划的重要補充信息。

  1、Using filesort:說明mysql會對數據使用一個外部的索引排序,而不是按照表內的索引順序進行讀取。MySQL中無法利用索引完成的排序操作稱為“文件排序;

  2、Using temporary:用臨時表保存中間結果,常用於GROUP BY ORDER BY操作中,一般看到它說明查詢需要優化了,就算避免不了臨時表的使用也要盡量避免硬盤臨時表的使用;

  3、Not existsMYSQL優化了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操作,在找到第一匹配的行后它將停止找更多的行;  

 

 

本文根據平時使用並結合其他資料整理以作為筆記備忘,文中如有存在描述不正確,歡迎指正、補充!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM