1. 程式人生 > >Mysql 效能優化Explain詳解

Mysql 效能優化Explain詳解


explain

功能
我們在日常使用中,使用慢查詢找到執行時間比較久的查詢,然後使用SHOW STATUS、SHOW PROFILE、和explain做單條語句的分析。
使用explain關鍵字可以模擬優化器執行sql查詢語句,從而知道Mysql是如何處理你的sql語句的。分析你的查詢語句或者表結構的效能瓶頸。


具體可以分析哪些

  1. 表的讀取順序
  2. 資料讀取操作的操作型別
  3. 哪些索引可以使用
  4. 哪些索引被實際使用
  5. 表之間的引用
  6. 每張表有多少行被優化器查詢


使用語法
explain sql語句

 

 

得到了什麼結果
expain出來的資訊有10列,分別是id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra


欄位概要解釋:

  • id:選擇識別符號
  • select_type:表示查詢的型別。
  • table:輸出結果集的表
  • partitions:匹配的分割槽
  • type:表示表的連線型別
  • possible_keys:表示查詢時,可能使用的索引
  • key:表示實際使用的索引
  • key_len:索引欄位的長度
  • ref:列與索引的比較
  • rows:掃描出的行數(估算的行數)
  • filtered:按表條件過濾的行百分比
  • Extra:執行情況的描述和說明

 

欄位詳細解釋

一、 id
SQL執行查詢的順序的標識
1. id相同時,執行順序由上至下

2. id不同時,如果是子查詢,id的序號會遞增,id值越大優先順序越高,越先被執行

3. id相同和不同同時存在,id如果相同,可以認為是一組,從上往下順序執行;在所有組中,id值越大,優先順序越高,越先執行

 

 

二、select_type
查詢中每個select子句的型別,主要用於區別普通查詢、聯合查詢、子查詢等複雜查詢
(1) SIMPLE(簡單SELECT,不使用UNION或子查詢等)
(2) PRIMARY(子查詢中最外層查詢,查詢中若包含任何複雜的子部分,最外層的select被標記為PRIMARY)
(3) UNION(UNION中的第二個或後面的SELECT語句)
(4) DEPENDENT UNION(UNION中的第二個或後面的SELECT語句,取決於外面的查詢)

(5) UNION RESULT(UNION的結果,union語句中第二個select開始後面所有select)
(6) SUBQUERY(子查詢中的第一個SELECT,結果不依賴於外部查詢)
(7) DEPENDENT SUBQUERY(子查詢中的第一個SELECT,依賴於外部查詢)
(8) DERIVED(派生表的SELECT, FROM子句的子查詢)
(9) UNCACHEABLE SUBQUERY(一個子查詢的結果不能被快取,必須重新評估外連結的第一行)


三、table
顯示這一步所訪問資料庫中表名稱(顯示這一行的資料是關於哪張表的)


四、type

表示MySQL在表中找到所需行的方式,又稱“訪問型別”,常見型別如下:

 ALL, index,  range, ref, eq_ref, const, system, NULL

從左到右,效能從最差到最好

 

 一般來說。得保證查詢至少達到range級別,最好能達到ref。

所有的訪問型別排序:

system:表只有一行記錄(等於系統表),這是const型別的特別,平時不會出現,這個可以忽略不計。

const:表示通過索引一次就找到了,const用於比較primary key或者unique索引,因為只匹配一行資料,所以很快
如將主鍵置於where列表中,Mysql就能將該查詢轉換為一個常量

eq_ref:唯一性索引掃描,對於每個索引鍵,表只只有一條記錄與之匹配。常見於主鍵或唯一索引掃描

ref:非唯一性索引掃描,返回匹配某個單獨值的所有行,本質上也是一種索引訪問,它返回匹配某個單獨值的行,然而,它可能會找到多個符合條件的行,索引他應該屬於查詢和掃描的混合體

range:只檢索給定範圍的行,使用一個索引來選擇行。
key列顯示使用了哪個索引,一般就是在你的where語句中出現了between、<、>、in等的查詢
這種範圍掃描索引掃描比全表掃描要好,因為它只需要開始於索引的某一點,面結束另一點,不用掃描全部索引。

index: Full Index Scan,index與ALL區別為index型別只遍歷索引樹,這通常比ALL快,因為索引檔案通常比資料檔案小,

也就是說雖然ALL和Index都是讀全表,但Index是從索引中讀取的,而ALL都是從磁碟中讀的。

ALL:Full Table Scan, MySQL將遍歷全表以找到匹配的行。NULL: MySQL在優化過程中分解語句,執行時甚至不用訪問表或索引,例如從一個索引列裡選取最小值可以通過單獨索引查詢完成。

 

五、possible_keys
顯示可能應用在這張表中的索引,一個或多個。
查詢涉及到的欄位上若存在索引,則該索引將被列出,但不一定被查詢實際使用。
簡單來說,mysql認為這條查詢可能用到哪些索引。

 

六、Key

key列顯示MySQL實際決定使用的鍵(索引),必然包含在possible_keys中

如果沒有選擇索引,鍵是NULL。要想強制MySQL使用或忽視possible_keys列中的索引,在查詢中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

 

七、key_len

表示索引中使用的位元組數,可通過該列計算查詢中使用的索引的長度(key_len顯示的值為索引欄位的最大可能長度,並非實際使用長度,即key_len是根據表定義計算而得,不是通過表內檢索出的)

同樣的查詢結果夏,不損失精確性的情況下,長度越短越好 。

 

八、ref

顯示索引的哪一列被使用了,如果可能的話,是一個常數,哪些列或者常量被用於查詢索引列上的值。

 

九、rows

 估算出結果集行數,表示MySQL根據表統計資訊及索引選用情況,估算的找到所需的記錄所需要讀取的行數

 

十、Extra

該欄位包含MySQL解決查詢的詳細資訊,有以下幾種情況:

Using filesort:

說明mysql會對資料使用一個外部的索引排序,而不是按照表內的索引順序進行讀取。

Mysql中無法利用索引完成的排序操作稱為“檔案排序”,如果出現,要優化此查詢。

簡單來說:Mysql並未按照你建立的索引去查詢,

 

Using temporary:

使用了臨時表中儲存中間結果,Mysql在對查詢結果排序時使用臨時表。常見於排序order by和分組查詢group by。

 

Using index:

表示相應的select操作中使用了覆蓋索引(Covering Index),避免訪問了表的資料行,效率不錯。

如果同時出現using where,表明索引被用於來執行索引鍵值的查詢。

如果沒有同時出現wing where,表明索引用來讀取資料而非執行查詢動作。

 

Using where :

表明使用了where過濾

 

Using join buffer:

使用了連線快取

 

impossible where:

where子句中的值總是false,不能用來獲取任何元