當一個 明顯異常慢時,可以尋找的方向是索引及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:在
SELECT
或WHERE
列表中包含了子查詢 - DEPENDENT SUBQUERY:首先
SELECT
在子查詢中,依賴於外部查詢 - DERIVED:在
FROM
中包含的子查詢 - MATERIALIZED: 在子查詢的
MATERIALIZED VIEW
- UNCACHEABLE SUBQUERY:不能緩存結果的子查詢,並且必須對外部查詢的每一行進行重新評估
- UNCACHEABLE UNION:第二個或更後一個選擇
UNION
屬於不可緩解的子查詢
- SIMPLE:查詢中不包含子查詢或者
- 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:針對每一筆記錄進行完全掃描,此為最壞的情況,應該盡量避免。