Explain文法:explain select … from … [where ...]
例如:explain select * from news;
輸出:
+—-+————-+——-+——-+——————-+———+———+——-+——+——-+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+—-+————-+——-+——-+——————-+———+———+——-+——+——-+
下面對各個屬性進行瞭解:
1、id:這是SELECT的查詢序號
2、select_type:select_type就是select的類型,可以有以下幾種:
SIMPLE:簡單SELECT(不使用UNION或子查詢等)
PRIMARY:最外面的SELECT
UNION:UNION中的第二個或後面的SELECT語句
DEPENDENT UNION:UNION中的第二個或後面的SELECT語句,取決於外面的查詢
UNION RESULT:UNION的結果。
SUBQUERY:子查詢中的第一個SELECT
DEPENDENT SUBQUERY:子查詢中的第一個SELECT,取決於外面的查詢
DERIVED:匯出表的SELECT(FROM子句的子查詢)
3、table:顯示這一行的資料是關於哪張表的
4、type:這列最重要,顯示了串連使用了哪種類別,有無使用索引,是使用Explain命令分析效能瓶頸的關鍵項之一。
結果值從好到壞依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery
> range > index > ALL
一般來說,得保證查詢至少達到range層級,最好能達到ref,否則就可能會出現效能問題。
5、possible_keys:列指出MySQL能使用哪個索引在該表中找到行
6、key:顯示MySQL實際決定使用的鍵(索引)。如果沒有選擇索引,鍵是NULL
7、key_len:顯示MySQL決定使用的鍵長度。如果鍵是NULL,則長度為NULL。使用的索引的長度。在不損失精確性的情
況下,長度越短越好
8、ref:顯示使用哪個列或常數與key一起從表中選擇行。
9、rows:顯示MySQL認為它執行查詢時必須檢查的行數。
10、Extra:包含MySQL解決查詢的詳細資料,也是關鍵參考項之一。
Distinct
一旦MYSQL找到了與行相聯合匹配的行,就不再搜尋了
Not exists
MYSQL 最佳化了LEFT JOIN,一旦它找到了匹配LEFT JOIN標準的行,
就不再搜尋了
Range checked for each
Record(index map:#)
沒有找到理想的索引,因此對於從前面表中來的每一 個行組合,MYSQL檢查使用哪個索引,並用它來從表中返回行。
這是使用索引的最慢的串連之一
Using filesort
看 到這個的時候,查詢就需要最佳化了。MYSQL需要進行額外的步驟來發現如何對返回的行排序。它根據連線類型以及
儲存排序索引值和匹配條件的全部行的行指標來 排序全部行
Using index
列資料是從僅僅使用了索引中的資訊而沒有讀取實際的行動的表返回的,這發生在對錶 的全部的請求列都是同一個索
引的部分的時候
Using temporary
看到這個的時候,查詢需要最佳化了。這 裡,MYSQL需要建立一個暫存資料表來儲存結果,這通常發生在對不同的列集進行
ORDER BY上,而不是GROUP BY上
Using where
使用了WHERE從句來限制哪些行將與下一張表匹配或者是返回給使用者。如果不想返回表中的全部行,並且連線類型ALL
或index, 這就會發生,或者是查詢有問題
其他一些Tip:
當type 顯示為 “index” 時,並且Extra顯示為“Using Index”, 表明使用了覆蓋索引。
附上一些欄位說明
ID:MySQL Query Optimizer選定的執行計畫中查詢的序號。
Select_type:所使用的查詢類型,主要有以下這幾種查詢類型。
DEPENDENT SUBQUERY:子查詢內層的第一個SELECT,依賴於外部查詢的結果集。
DEPENDENT UNION:子查詢中的UNION,且為UNION中從第二個SELECT開始的後面所有SELECT,同樣依賴於外部查詢的結
果集。
PRIMARY:子查詢中的最外層查詢,注意並不是主鍵查詢。
SIMPLE:除子查詢或UNION之外的其他查詢。
SUBQUERY:子查詢內層查詢的第一個SELECT,結果不依賴於外部查詢結果集。
UNCACHEABLE SUBQUERY:結果集無法緩衝的子查詢。
UNION:UNION語句中第二個SELECT開始後面的所有SELECT,第一個SELECT為PRIMARY。
UNION RESULT:UNION 中的合并結果。
Table:顯示這一步所訪問的資料庫中的表的名稱。
Type:告訴我們對錶使用的訪問方式,主要包含如下集中類型。
all:全表掃描。
const:讀常量,最多隻會有一條記錄匹配,由於是常量,實際上只須要讀一次。
eq_ref:最多隻會有一條匹配結果,一般是通過主鍵或唯一鍵索引來訪問。
fulltext:進行全文索引檢索。
index:全索引掃描。
index_merge:查詢中同時使用兩個(或更多)索引,然後對索引結果進行合并(merge),再讀取表資料。
index_subquery:子查詢中的返回結果欄位組合是一個索引(或索引組合),但不是一個主鍵或唯一索引。
rang:索引範圍掃描。
ref:Join語句中被驅動表索引引用的查詢。
ref_or_null:與ref的唯一區別就是在使用索引引用的查詢之外再增加一個空值的查詢。
system:系統資料表,表中只有一行資料;
unique_subquery:子查詢中的返回結果欄位組合是主鍵或唯一約束。
Possible_keys:該查詢可以利用的索引。如果沒有任何索引可以使用,就會顯示成null,這項內容對最佳化索引時的調
整非常重要。
Key:MySQL Query Optimizer 從 possible_keys 中所選擇使用的索引。
Key_len:被選中使用索引的索引鍵長度。
Ref:列出是通過常量(const),還是某個表的某個欄位(如果是join)來過濾(通過key)的。
Rows:MySQL Query Optimizer 通過系統收集的統計資訊估算出來的結果集記錄條數。
Extra:查詢中每一步實現的額外細節資訊,主要會是以下內容。
Distinct:尋找distinct 值,當mysql找到了第一條匹配的結果時,將停止該值的查詢,轉為後面其他值查詢。
Full scan on NULL key:子查詢中的一種最佳化方式,主要在遇到無法通過索引訪問null值的使用。
Range checked for each record (index map: N):通過 MySQL 官方手冊的描述,當 MySQL Query Optimizer 沒有
發現好的可以使用的索引時,如果發現前面表的列值已知,部分索引可以使用。對前面表的每個行組合,MySQL檢查是
否可以使用range或 index_merge存取方法來索取行。
SELECT tables optimized away:當我們使用某些彙總函式來訪問存在索引的某個欄位時,MySQL Query Optimizer
會通過索引直接一次定位到所需的資料行完成整個查詢。當然,前提是在 Query 中不能有 GROUP BY 操作。如使用
MIN()或MAX()的時候。
Using filesort:當Query 中包含 ORDER BY 操作,而且無法利用索引完成排序操作的時候,MySQL Query Optimizer
不得不選擇相應的排序演算法來實現。
Using index:所需資料只需在 Index 即可全部獲得,不須要再到表中取資料。
Using index for group-by:資料訪問和 Using index 一樣,所需資料只須要讀取索引,當Query 中使用GROUP BY或
DISTINCT 子句時,如果分組欄位也在索引中,Extra中的資訊就會是 Using index for group-by。
Using temporary:當 MySQL 在某些操作中必須使用暫存資料表時,在 Extra 資訊中就會出現Using temporary 。主要常
見於 GROUP BY 和 ORDER BY 等操作中。
Using where:如果不讀取表的所有資料,或不是僅僅通過索引就可以擷取所有需要的資料,則會出現 Using where
資訊。
Using where with pushed condition:這是一個僅僅在 NDBCluster儲存引擎中才會出現的資訊,而且還須要通過打
開 Condition Pushdown 最佳化功能才可能被使用。控制參數為 engine_condition_pushdown 。
Impossible WHERE noticed after reading const tables:MySQL Query Optimizer 通過收集到的統計資訊判斷出不
可能存在結果。
No tables:Query 語句中使用 FROM DUAL或不包含任何 FROM子句。
Not exists:在某些左串連中,MySQL Query Optimizer通過改變原有 Query 的組成而使用的最佳化方法,可以部分減
少資料訪問次數