explain使用介紹
id:執行編號,標識select所屬的行。如果在語句中沒子查詢或關聯查詢,只有唯一的select,每行都將顯示1。否則,內層的select語句一般會順序編號,對應於其在原始語句中的位置
select_type:顯示本行是簡單或復雜select。如果查詢有任何復雜的子查詢,則最外層標記為PRIMARY(DERIVED、UNION、UNION RESUlT)
table:訪問引用哪個表(引用某個查詢,如“derived3”)
type:數據訪問/讀取操作類型(ALL、index、range、ref、eq_ref、const/system、NULL)
possible_keys:揭示哪一些索引可能有利於高效的查找
key:顯示mysql決定采用哪個索引來優化查詢
key_len:顯示mysql在索引里使用的字節數
ref:顯示了之前的表在key列記錄的索引中查找值所用的列或常量
rows:為了找到所需的行而需要讀取的行數,估算值,不精確。通過把所有rows列值相乘,可粗略估算整個查詢會檢查的行數。整編:微信公眾號,搜雲庫技術團隊,ID:souyunku
Extra:額外信息,如using index、filesort等
Using filesort表示通過對返回數據進行排序
Using temporary表示查詢有使用臨時表, 一般出現於排序, 分組和多表join的情況, 查詢效率不高, 仍需要進行優化,出現臨時表的原因還可能是數據量過大使用了臨時表進行分組運算
重點關注type,type類型的不同竟然導致性能差六倍!!!
type顯示的是訪問類型,是較為重要的一個指標,結果值從好到壞依次是:system > const > eqref > ref > fulltext > refornull > indexmerge > uniquesubquery > indexsubquery > range > index > ALL ,一般來說,得保證查詢至少達到range級別,最好能達到ref。
All:最壞的情況,全表掃描
index:和全表掃描一樣。只是掃描表的時候按照索引次序進行而不是行。主要優點就是避免了排序, 但是開銷仍然非常大。如在Extra列看到Using index,說明正在使用覆蓋索引,只掃描索引的數據,它比按索引次序全表掃描的開銷要小很多
range:范圍掃描,一個有限制的索引掃描。key 列顯示使用了哪個索引。當使用=、 <>、>、>=、<、<=、IS NULL、<=>、BETWEEN 或者 IN 操作符,用常量比較關鍵字列時,可以使用 range |
ref:一種索引訪問,它返回所有匹配某個單個值的行。此類索引訪問只有當使用非唯一性索引或唯一性索引非唯一性前綴時才會發生。這個類型跟eq_ref不同的是,它用在關聯操作只使用了索引的最左前綴,或者索引不是UNIQUE和PRIMARY KEY。ref可以用於使用=或<=>操作符的帶索引的列。
eq_ref:最多只返回一條符合條件的記錄。使用唯一性索引或主鍵查找時會發生 (高效)
const:當確定最多只會有一行匹配的時候,MySQL優化器會在查詢前讀取它而且只讀取一次,因此非常快。當主鍵放入where子句時,mysql把這個查詢轉為一個常量(高效)
system:這是const連接類型的一種特例,表僅有一行滿足條件。
Null:意味說mysql能在優化階段分解查詢語句,在執行階段甚至用不到訪問表或索引(高效)
舉例SQL: EXPLAIN select * from student group by age
解決方案:
1、盡量避免在where子句中對字段進行函數操作,這將導致存儲引擎放棄使用索引而進行全表掃描。對於需要計算的值最好通過程序計算好傳入而不是在sql語句中做計算
2、group by實質是先排序后分組,也就是分組之前必排序。通過分組的時候禁止排序優化sql
舉例:group by name order by null
3、使用分組查詢、范圍查詢,而不是全量查詢