(4) MySQL中EXPLAIN執行計劃分析

一. 執行計劃能告訴咱們什麼?

  • SQL如何使用索引
  • 聯接查詢的執行順序
  • 查詢掃描的數據函數

二. 執行計劃中的內容

SQL執行計劃的輸出可能爲多行,每一行表明對一個數據庫對象的操做sql

1. ID列

  • ID列中的若是數據爲一組數字,表示執行SELECT語句的順序;若是爲NULL,則說明這一行數據是由另外兩個SQL語句進行 UNION操做後產生的結果集
  • ID值相同時,說明SQL執行順序是按照顯示的從上至下執行的
  • ID值不一樣時,ID值越大表明優先級越高,則越先被執行

演示

能夠看到上面的執行計劃返回了3行結果,id列的值能夠看做是SQL中所具備的SELECT操做的序號
因爲上述SQL中只有一個SELECT,因此id全爲1,所以,咱們就要按照由上至下讀取執行計劃
按照咱們的SQL語句,咱們會認爲執行順序是a,b,c,可是經過上圖能夠發現,Mysql並非完成按照SQL中所寫的順序來進行表的關聯操做的
執行對錶的執行順序爲a,c,b,這是因爲MySQL優化器會根據表中的索引的統計信息來調整表關聯的實際順序數據庫

2. SELECT_TYPE列

含義
SIMPLE 不包含子查詢或是UNION操做的查詢
PRIMARY 查詢中若是包含任何子查詢,那麼最外層的查詢則被標記爲PRIMARY
SUBQUERY SELECT 列表中的子查詢
DEPENDENT SUBQUERY 依賴外部結果的子查詢
UNION Union操做的第二個或是以後的查詢的值爲union
DEPENDENT UNION 當UNION做爲子查詢時,第二或是第二個後的查詢的select_type值
UNION RESULT UNION產生的結果集
DERIVED 出如今FROM子句中的子查詢

3. TABLE列

包含如下幾種結果:服務器

輸出去數據行所在表的名稱,若是表取了別名,則顯示的是別名
<union M,N>: 由ID爲M,N查詢union產生的結果集
<derived N>/<subquery N> :由ID爲N的查詢產生的結果

4. PARTITIONS列:

查詢匹配的記錄來自哪個分區
對於分區表,顯示查詢的分區ID
對於非分區表,顯示爲NULL

5. TYPE列

按性能從高至低排列以下:函數

含義
system 這是const聯接類型的一個特例,當查詢的表只有一行時使用
const 表中有且只有一個匹配的行時使用,如對主鍵或是惟一索引的查詢,這是效率最高的聯接方式
eq_ref 惟一索引或主鍵索引查詢,對應每一個索引鍵,表中只有一條記錄與之匹配
ref 非惟一索引查找,返回匹配某個單獨值的全部行
ref_or_null 相似於ref類型的查詢,可是附加了對NULL值列的查詢
index_merge 該聯接類型表示使用了索引合併優化方法
range 索引範圍掃描,常見於between、>、<這樣的查詢條件
index FULL index Scan 全索引掃描,同ALL的區別是,遍歷的是索引樹
ALL FULL TABLE Scan 全表掃描,這是效率最差的聯接方式

6. Extra列

包含MySQL如何執行查詢的附加信息性能

含義
Distinct 優化distinct操做,在找到第一個匹配的元素後即中止查找
Not exists 使用not exists來優化查詢
Using filesort 使用額外操做進行排序,一般會出如今order by或group by查詢中
Using index 使用了覆蓋索引進行查詢
Using temporary MySQL須要使用臨時表來處理查詢,常見於排序,子查詢,和分組查詢
Using where 須要在MySQL服務器層使用WHERE條件來過濾數據
select tables optimized away 直接經過索引來得到數據,不用訪問表,這種狀況一般效率是最高的

7. POSSIBLE_KEYS列

  • 指出MySQL能使用哪些索引來優化查詢
  • 查詢列所涉及到的列上的索引都會被列出,但不必定會被使用

8. KEY列

  • 查詢優化器優化查詢實際所使用的索引
  • 若是表中沒有可用的索引,則顯示爲NULL
  • 若是查詢使用了覆蓋索引,則該索引僅出如今Key列中

9. KEY_LEN列

顯示MySQL索引所使用的字節數,在聯合索引中若是有3列,假如3列字段總長度爲100個字節,Key_len顯示的可能會小於100字節,好比30字節,這就說明在查詢過程當中沒有使用到聯合索引的全部列,只是利用到了前面的一列或2列優化

  • 表示索引字段的最大可能長度
  • Key_len的長度由字段定義計算而來,並不是數據的實際長度

10. Ref列

  • 表示當前表在利用Key列記錄中的索引進行查詢時所用到的列或常量

11. rows列

  • 表示MySQL經過索引的統計信息,估算出來的所需讀取的行數(關聯查詢時,顯示的是每次嵌套查詢時所須要的行數)
  • Rows值的大小是個統計抽樣結果,並不十分準確

12. Filtered列

  • 表示返回結果的行數佔需讀取行數的百分比
  • Filtered列的值越大越好(值越大,代表實際讀取的行數與所須要返回的行數越接近)
  • Filtered列的值依賴統計信息,因此一樣也不是十分準確,只是一個參考值

三. 執行計劃的限制

  • 沒法展現存儲過程,觸發器,UDF對查詢的影響
  • 沒法使用EXPLAIN對存儲過程進行分析
  • 早期版本的MySQL只支持對SELECT語句進行分析
相關文章
相關標籤/搜索