SQL 之 EXPLAIN 語法詳解

EXPLAIN 命令可以查看SQL執行計劃的信息,可以作爲日常優化SQL的工具

誤區

  1. 用 explain 時 sql 不會執行。
    解答:如果查詢在 FROM 中子句包括子查詢,MySQL會執行子查詢,將其結果放到一個臨時表中,然後完成外層查詢優化。這意味着開銷較大的子查詢或使用臨時表算法的視圖會給服務器帶來大量工作。
  2. explain 很準確。
    解答:explain只是一個近似結果,會有一些相關限制(具體去查書吧。。平時也用不到,explain 只是給我們一個sql執行的參考)。
  3. mysql5.6 版本之前 explain 只解釋 select 查詢。(你可以重寫某些非 select 語句來利用它)

EXPALIN 列詳解

id

  • 編號,標識 select 所屬的行,如果沒有子查詢或者連表查詢,那麼就只有1個 select id 爲 1。
  • 同一級連表的id 都爲1,第一個子查詢爲2,再深層的子查詢,你懂得。
  • union 查詢時,最後一行會顯示一張匿名臨時表,id 爲 null

select_type

  • SIMPLE: 查詢不使用UNION或子查詢
  • PRIMARY: 複雜查詢時,最外層的SELECT
  • SUBQUERY:子查詢中的第一個SELECT
  • DERIVED:FROM子句的子查詢的SELECT,MySQL會遞歸執行,並將結果放到一個臨時表中,稱爲“派生表”(子查詢中派生來的)
  • UNION:UNION中的第二個或後面的SELECT語句
  • UNION RESULT:用來從 UNION 的匿名臨時表檢索結果的 SELECT
  • DEPENDENT:SELECT 依賴於外層的查詢
  • UNCACHEABLE:SELECT 的某些特性阻止結果被緩存於一個 Item_cache 中

table

對應行正在訪問的表

type

訪問該表時的訪問類型
- all 全表掃描(例外:使用了 limit 或者 Extra 列中顯示了 “Using distinct/not exists”)
- index 和全表掃描一樣,只是是按照索引次序而不是行,優點是避免了排序,缺點是要承擔按索引次序讀取整個表的開銷。如果在 Extra 中看到了 “Using index” 證明只掃描了索引的數據,開銷小很多。
- range 範圍掃描,顯然是查詢中有 between 或者 > < ,有時候是 IN 或 OR
- ref 索引訪問
- eq_ref 主鍵或者唯一索引訪問,MySQL知道最多隻返回一條符合條件的記錄
- const,system MYSQL對查詢的某部分進行優化並將其轉化爲一個常量時的訪問類型,比如 where 子句中放入了主鍵
- NULL 意味着MYSQL能在優化階段分解查詢語句,不用再訪問表或者索引

possible_keys

查詢可以使用哪些索引,這些索引是在優化過程早期創建的,可能對於後續優化沒有用處。

key

顯示MySQL實際決定使用的索引

possible_keys 揭示了哪個索引能有助於高效的行查找,key 顯示的是優化採用哪一個索引可以最小化查詢成本

key_len

MYSQL 在索引中使用的字節數,可以推斷出具體哪一個字段使用了索引

ref

顯示了 key 列記錄的索引中查找值所用的列或常量

rows

MYSQL 估計爲了找到所需的行所要讀取的行數。
注意這裏僅僅是MYSQL認爲要檢查的行數,並不是結果行數

filtered

MYSQL 5.1 版本之後纔有
在使用 EXPLAIN EXTENDED 時會出現
將這個值與rows中的值相乘,就是MYSQL估算出它和查詢計劃中前一個表的關聯行數

Extra

  • Using index:MYSQL 將使用覆蓋索引
  • Using where:將在存儲引擎檢索行後再進行過濾,暗示:查詢可受益於不同的索引
  • Using temporary:MYSQL 在對查詢結果排序時會使用一個臨時表
  • Using filesort:MYSQL 會對查詢結果進行一個外部索引排序
  • range checked for each record (index map: #):MySQL 發現沒有好用的索引,新的索引將在連接的每一行上重新估算。N 是顯示在 possible_keys 列中索引的位圖,是冗餘的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章