Mysql中Explain詳解

當咱們使用索引的時候,一般會用explain來檢查咱們索引使用的狀況。sql

id列:服務器

這一列老是包含一個編號,標示select所屬的行。若是在語句當中沒有子查詢或聯合,那麼只會有的select,因而每個在這個列中都將顯示一個1.不然,內層的select語句通常會順序編號,對應與其在原始語句中的位置。性能

Mysql將select查詢分爲簡單和複雜類型,複雜類型可分紅三大類:簡單子查詢,所謂的派生表(在from字句中的子查詢),以及union查詢。優化

一、這個是簡單的子查詢:排序

二、from子句中的子查詢和聯合給id列增長了更多的複雜性。下面是一個from字句中的基本子查詢。遞歸

這個查詢語句執行時有一個匿名臨時表。MySQL內部經過別名(der)在外層查詢中引用這個臨時表,在更復雜的查詢中能夠看到ref列。索引

三、下面是一個UNION查詢。博客

Explain select 1 union all select 1;it

注意union結果輸出中的額外行。union結果老是放在一個匿名臨時表中,以後MySQL將結果讀取到臨時表臨時表外。臨時表並不在原sql中出現,所以他的id列是null,與以前的例子相比(演示子查詢的那個from字句中),從這個查詢產生的臨時表在結果中出如今最後一行,而不是第一行。io

select_type列

這一列顯示對應行是簡單仍是複雜的select(若是是後者,那麼是三種複雜類型的哪種),simple值意味着查詢中不包括子查詢和union。若是查詢有任何複雜的子部分,則最外層部分標記爲primary,其餘部分標記以下。

subquery:包含在select列表中的子查詢中的select(就是再也不from字句中)標記爲subquery。

derived:derived值用來表示包含在from字句中的子查詢中的select,MySQL會遞歸執行並將結果放到一個臨時表中。服務器內部稱其爲「派生表」,由於該臨時表是從子查詢中派生出來的。

union:在union中的第二個和隨後的select被標記爲union。第一個select被標記就好像它以部分外查詢來執行。這就是以前的例子中的union中的第一個select顯示爲primary的緣由。若是union被from字句中的子查詢包含,那麼它的第一個select會標記爲derived;

union result

    用來從union的匿名臨時表檢索結果的select被標記爲union result。

Type列

訪問SQl的類型,也就是MySQL決定查找表中的行。下面是最重要的訪問方法,一次從差到最優。

ALL:這就是人們所稱的全表掃描,一般意味着MySQL必須掃描整張表,從頭至尾,去找到須要的行。(這裏也有一個覺得,例如在查詢中裏使用limit,或者在extra列中顯示「using distinct/not exists」。)

Index:這個跟全表掃描同樣,只是MySQL掃描表時按照索引的次序進行而不是行。他的主要優勢是避免了排序;最大的缺點是要承擔按索引次序讀取整個表的開銷。這一般意味着若按隨機次序訪問行,開銷將會很是大。

Range:範圍掃描就是一個有限制的索引掃描,它開始於索引的某一點,返回匹配這個值域的行。這比全索引掃描好一些,由於它用不到遍歷所有索引。顯而易見的範圍掃描時帶有between或在where字句帶有>的查詢。

當MySQL使用索引區查找一系列值的時候,例如in()和or()列表,也會顯示範圍掃描。然而二者至關於不一樣的訪問類型,在性能上有重要的差距。在我博客有相關記載。

Ref:這是一種索引訪問(有時候也叫索引查找),他返回全部匹配某個單個值的行。然而,他可能會找到多個符合條件的查詢,所以,它是查找和掃描的混合體。此類索引訪問只有當使用非惟一索引或者惟一性索引的非惟一性前綴時才能發生。把它叫作ref是由於索引要跟某個參考值相比較。這個參數值或者是一個常數,或者是來自多表查詢前一個表裏的結果值。

Eq_ref:使用這種索引查找,MySQL知道最多隻返回一條符合條件的記錄。這種訪問方法能夠再MySQL使用主鍵或者惟一性索引查找時看到,它會將他們與某個參考值做比較。MySQL對於這類訪問類型的優化作的很是好,由於他知道無須估計匹配行的範圍或在找到匹配行後再繼續查找。

Const,system:當MySQL能對查詢的某部分進行優化並將其轉換成一個常量時,他就會使用這些訪問類型。舉例來講,若是你經過將某一行的主鍵放入where子句裏的方式來選取此行的主鍵,MySQL就能把這個查詢轉換成一個常量。而後就能夠高效地將表從聯接執行中移除。

Null:這種訪問方式意味着MySQL能在優化階段分解查詢語句,在執行階段甚至用不着在訪問表或者索引。例如,從一個索引列裏選取最小值能夠經過單獨查找索引來完成,不須要在執行時訪問表。

 

Key列:

這一列顯示了查詢可使用哪些索引。

Ref列:這一列顯示以前的表在key列記錄的數據索引中查找值索引的列或者常量。

Rows列:估計這個查找到所須要的行而讀取的行數。是個約數。

Extra列:

這一列包含的是不適合在其餘列顯示的額外信息。

「Using index」:此值表示MySQL將使用覆蓋索引,以免訪問表。不要把覆蓋索引和index類型弄混。

「Using where」:此值覺得這MySQL服務器將在存儲引擎檢索行後再進行過濾。許多where條件裏涉及到索引中的列,當(而且若是)它讀取索引時,就能被存儲引擎檢驗,所以不是全部帶有where子句查詢都會顯示「using where」。有時,「using where」 的出現就是一個暗示,查詢可收益與不一樣的索引。

Using temporary:這意味着MySQL在對查詢結果排序時會使用一個臨時表。

Using filesort:這意味着MySQL會對結果使用一個外部索引排序,而不是按索引次序從表中讀取行。

「Range checked for each record (index map:N)」

這個值意味着沒有好用的索引,新的索引將在聯接的每一行上從新估算。

相關文章
相關標籤/搜索