[Mysql][調校]秀出SQL語句的執行計畫(Explain)

當一個 明顯異常慢時,可以尋找的方向是索引及SQL語句的撰寫方式,我們也可以使用Explain秀出SQL語法的執行時的狀況,因為今天上課微軟的資料庫MSSQL有一個很方便的功能叫執行計畫,可以知道每個階段的查詢時間,MYSQL 也有類似的,但是恐怕還沒這麼方便,依照MySQL手冊使用方法,只需要在SQL語法前,加上Explain 即可,利用以下方式及查詢結果就可以知道 哪裡可以在調校優化了。

方法如下:

Explain SELECT * FROM your_table ;

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE your_table ALL NULL NULL NULL NULL 290 NULL

欄位說明:

  • id
    • 包含一組數字,表示查詢中執行select子句或操作表的順序;當id值一樣的時候,執行順序由上往下;
  • select_type
    • SIMPLE:查詢中不包含子查詢或者UNION
    • PRIMARY:查詢中若包含任何復雜的子部分,最外層查詢則被標記為PRIMARY
    • UNION:若第二個SELECT出現在UNION之後,則被標記為UNION
    • DEPENDENT UNION:第二個或更後一個SELECT語句在一個 UNION,依賴於外部查詢
    • UNION RESULT:從UNION表獲取結果的SELECT被標記為
    • SUBQUERY:在SELECTWHERE列表中包含了子查詢
    • DEPENDENT SUBQUERY:首先SELECT在子查詢中,依賴於外部查詢
    • DERIVED:在FROM中包含的子查詢
    • MATERIALIZED: 在子查詢的MATERIALIZED VIEW
    • UNCACHEABLE SUBQUERY:不能緩存結果的子查詢,並且必須對外部查詢的每一行進行重新評估
    • UNCACHEABLE UNION:第二個或更後一個選擇UNION 屬於不可緩解的子查詢
  • table:關連到的資料表
  • type:使用關聯查詢的類型(效率從好到壞)
    • const、system:當MySQL對查詢某部分進行優化,並轉換為一個常量時,使用這些類型訪問。如將主鍵置於where列表中,MySQL就能將該查詢轉換為一個常量,效率最好
    • eq_ref:唯一性索引掃描,對於每個索引鍵,表中只有一條記錄與之匹配。常見於主鍵或唯一索引掃描,效率次好
    • ref:非唯一性索引掃描,返回匹配摸個單獨值的所有行。常見於使用非唯一索引或唯一索引的非唯一前綴進行的查找
    • fulltext:使用(全文索引)FULLTEXT進行。(MySQL Fulltext 不支援 InnoDB, 需要使用 MyISAM.)
    • ref_or_null:和ref類似,但是條件中包含對於NULL查詢
    • index_merge:MySQL查詢中使用INDEX_MERGE做查詢
    • range:range Index Scan,對索引的掃描開始於某一點,返回匹配值域的行,常見於between、<、>等的查詢
    • unique_subquery:in的後面是一個查詢主鍵字段的子查詢
    • index_subquery:主要是in的後面是查詢非唯一索引字段的子查詢
    • index:Full Index Scan,index與ALL區別為index類型只遍歷索引
    • ALL:Full Table Scan, MySQL進行了全表掃描,沒有索引,效率最差
  • possible_keys:指出MySQL能使用哪個索引在表中找到行,查詢涉及到的字段上若存在索引,則該索引將被列出,但不一定被查詢使用
  • key:顯示MySQL在查詢中實際使用的索引,若沒有使用索引,顯示為NULL。當查詢中若使用了覆蓋索引,則該索引僅出現在key列表中
  • key_len:表示索引中使用的字節數,可通過該列計算查詢中使用的索引的長度
  • ref:表示上述表的連接匹配條件,即那些列或常量被用於查找索引列上的值
  • rows:表示MySQL根據表統計信息及索引選用情況,估算的找到所需的記錄所需要讀取的行數
  • Extra:包含不適合在其他列中顯示但十分重要的額外信息:
    • Distinct:當MySQL找到相關連的資料時,就不再搜尋。
    • Not exists:MySQL優化 LEFT JOIN,一旦找到符合的LEFT JOIN資料後,就不再搜尋。
    • Range checked for each Record(index map:#):無法找到理想的索引。此為最慢的使用索引。
    • Using filesort:當出現這個值時,表示此SELECT語法需要優化。因為MySQL必須進行額外的步驟來進行查詢。
    • Using index:返回的資料是從索引中資料,而不是從實際的資料中返回,當返回的資料都出現在索引中的資料時就會發生此情況。
    • Using temporary:同Using filesort,表示此SELECT語法需要進行優化。此為MySQL必須建立一個暫時的資料表(Table)來儲存結果,此情況會發生在針對不同的資料進行ORDER BY,而不是GROUP BY
    • Using where:使用WHERE語法中的欄位來返回結果。
    • System:system資料表,此為const連接類型的特殊情況。
    • Const:資料表中的一個記錄的最大值能夠符合這個查詢。因為只有一行,這個值就是常數,因為MySQL會先讀這個值然後把它當做常數。
    • eq_ref:MySQL在連接查詢時,會從最前面的資料表,對每一個記錄的聯合,從資料表中讀取一個記錄,在查詢時會使用索引為主鍵或唯一鍵的全部。
    • ref:只有在查詢使用了非唯一鍵或主鍵時才會發生。
    • range:使用索引返回一個範圍的結果。例如:使用大於>或小於<查詢時發生。
    • index:此為針對索引中的資料進行查詢。
    • ALL:針對每一筆記錄進行完全掃描,此為最壞的情況,應該盡量避免。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *