Mysql中的explain檢視執行計劃
Mysql中的explain檢視執行計劃
1、explain是什麼?
檢視執行計劃。
2、怎麼使用?
explain + sql語句。
3、執行計劃包含的資訊:
id,select_type,table,type,possible_keys,key,key_len,ref,rows,Extra
4、各個欄位的意思:
(1)id: select查詢的序列號,包含一組數字,表示查詢中執行select字句或操作的順序。
id有三種值:
id相同,執行順序由上至下。
id不同,如果是子查詢,id的序號會遞增,id越大優先順序越高,先被執行。
id相同不同,如1,1,2,id相同可以認為是一組,從上往下順序執行。在所有組中,id越大,優先順序越高,越先被執行。
(2)select_type:查詢的型別,主要是用於區別普通查詢,聯合查詢,子查詢等的複雜查詢。
Select_type的值有:simple, primary, subQuery, derived, union, union result.
Simple:簡單的select查詢,查詢中不包含子查詢或者union;
Primary:主查詢,查詢中若包含任何子查詢,最外層查詢則被標記為主查詢;
subQuery:子查詢,在select或者where列表中包含子查詢。
Derived:臨時表,在from列表中包含的子查詢被標記為derived(衍生);
Union:第二個select出現在union之後,則被標記為union;
Union result:從union表中獲取結構的select;
(3)table:顯示這一行的資料是關於哪張表的;
(4)type:訪問型別排列;
顯示查詢使用了哪一種型別,從最好到最差依次是:
System > const > eq_ref > ref > range > index > ALL
一般來說,得保證查詢到range級別,最好能到ref級別。
值解釋:
System:表中只有一行記錄(等於系統表),這是const型別的特例,平時不會出現,這個可以忽略不計。
Const:表示通過索引一次就找到了,const用於比較primary key或者unique索引。因為只匹配一行資料,所以很快。例如將主鍵置於where列表中,mysql將該查詢轉為一個常量。
Eq_ref:唯一性索引掃描,對於每個索引鍵,表中只有一條記錄與之匹配。常見於主鍵或唯一索引掃描。
Ref:非唯一性索引掃描,返回匹配某個單獨值得所有行。
Range:只檢索給定範圍的行,使用一個索引來選擇行。Key列顯示使用了哪個索引,一般就是在你的where語句中出現了between, <, >, in等的查詢。這種範圍掃描比全表掃描,因為它只需要開始於索引的某一點,而結束於另一點,不用掃描全部索引。
Index:full index scan全索引掃描,index與all的區別為:index型別只遍歷索引樹,這通常比all快,因為索引檔案通常比資料檔案小。也就是說雖然index和all都是讀全表,但index是從索引中讀的,而all是從硬碟中讀的。
All:全表掃描,是最慢的型別。
(5)possible_keys:顯示可能應用在這張表中的索引,一個或者多個。
查詢涉及到的欄位上若存在索引,則該索引將被列出,但不一定被查詢實際使用。
(6)Key:實際使用的索引。
如果為null,則沒有使用索引。查詢中若出現了覆蓋索引,則該索引僅出現在key列表中。
(7)Key_len:表示索引中使用的位元組數,可通過該列計算查詢中使用的索引的長度。
在不損失精確性的情況下,長度越短越好。
Key_len顯示的值為索引欄位的最大可能長度,並非實際使用長度,即key_len是根據表定義計算而得,不是通過表內檢索出的。
(8)Ref:顯示索引的具體一列被使用了,也可能是一個const。
哪些列或者常量被用於查詢索引列上的值。
(9)Rows:根據表統計資訊及索引選用情況,大致估算出找到所需的記錄所需要讀取的行數。數值越低越好。
(10)Extra:不適合在其他列顯示,但十分重要的額外資訊。
Extra有如下幾個值:
Using filesort
Using temporary
Using index
Using where
using join buffer
impossible where,
Select tables optimized away
distinct
值的解釋:
Using filesort:
說明mysql會對資料使用一個外部的索引排序,而不是按照表內的索引順序進行讀取。Mysql中無法利用索引完成的排序操作稱為“檔案排序”。
Using temporary:
使用了臨時表儲存中間結果。常見於排序order by和分組查詢group by。
Using filesort和Using temporary都是不太好的結果,會影響效能。
Using index:表示相應的select操作中使用了覆蓋索引,避免訪問了表的資料行,效率不錯!
如果同時出現了using where,表明索引被用來執行索引鍵值的查詢;
如果沒有同時出現using where,表明索引用來讀取資料而非執行查詢動作。
Using where:表示使用了where過濾。
Using join buffer:使用了連線快取。
impossible where:表示where條件總是false。例如:where name=”zs” and name=”ls”;
Select tables optimized away:沒有group by子句下,基於索引優化Max/Min操作。
Distinct:優化distinct,在找到第一匹配的元組後即停止找到同樣值得動作。
編寫高質量的sql語句的幾點建議
1、儘量select具體欄位;
2、明確1條資料時,用limit 1;
3、儘量少用or;
4、優化limit分頁,limit 10000 10很慢。例如:(1)order by + 索引;(2)業務中限制頁數;
5、優化like,%放後面,遵循最佳左字首法則;
6、where 條件儘量限制住,不要返回不符合業務的多餘資料;
7、索引欄位儘量不要參與mysql內建函式 或者 其他表示式計算;
8、表連線優先考慮內連線,如果是left join,應該小表驅動大表;
9、儘量where條件少用 != ;
10、組合索引時,注意索引列的順序,遵循最左匹配原則;
11、如果要插入的資料過多,儘量批量儲存;
12、慎用distinct關鍵字,當過多欄位時,distinct多個欄位sql將很慢;
13、儘量不要用is null 或者 is not null,可以考慮用預設值;
14、當in後面資料量過大時,應該考慮用exists關鍵字來實現;
15、表連線時,儘量寫別名,查詢欄位也用“別名.”的方式;
16、儘量varchar代替char,除非欄位全是固定個字元;
17、字串一定要用“”引起來;
18、經常使用explain分析你的sql語句。
————————————————
版權宣告:本文為CSDN博主「pipizhen_」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連結及本宣告。
原文連結:https://blog.csdn.net/pipizhen_/article/details/115335294