​explain執行計劃分析

power_kai發表於2020-11-14

#id列

數字越大越先執行,如果數字一樣大,那麼就往從上往下依次執行,id列為null就標識這個是一個結果集,不需要使用它來進行查詢

 

#select_type列

simple:標識不需要union操作或者不包含子查詢的簡單select查詢,有連結查詢時,外層的查詢為simple,且只有一個

primary:一個需要union操作或者含有子查詢的select,位於最外層的查詢,select_type即為primary,且只有一個

union:union連線的兩個select查詢,第一個查詢是dervied派生表,除了第一個表外,第二個以後的表select_type都union

union_result:包含union的結果集,在union和union all語句中,因為它不需要參與查詢,所以id欄位為null

dependent_union:與union一樣,出現在union或者union all語句中,但是這個查詢要受到外部查詢的影響 #explain select * from film_category where film_id in (select film_id from film  union all select film_id from film_actor)\G

subquery:除了from子句中包含的子查詢外,其他地方出現的子查詢都可能是subquery

dependent_subquery:與dependent union類似,標識subquery的查詢要收到外部表查詢的影響

derived:from欄位中出現的子查詢,也叫做派生表,其他資料庫中可能叫做內聯檢視或者巢狀select

materialization:物化通過將子查詢結果作為一個臨時表來加快查詢速度,正常來說是常駐記憶體,下次查詢會再次引用臨時表

 

#table列

顯示的查詢表明,如果查詢使用了別名,那麼這裡顯示的是別名,如果不涉及對資料表的操作,

那麼這裡顯示null,如果顯示為監控好括起來<derived N>就表示這個是臨時表,後邊的N就是

執行計劃中的id,標識結果來自於這個查詢產生,如果是尖括號括起來的<union M,N>,與<derived N>類似,也是一個臨時表,標識這個結果來自於union查詢的id為M,N的結果集

 

#type列

system:表中只有一行資料或者是空表,且只能用於myisam和memory表,如果是Innodb引擎,type列在這個情況通常都是all或者index

const:使用唯一索引或者主鍵,返回記錄一定是1行記錄的等值where條件時,通常type是const,其他資料庫也叫做唯一索引掃描

eq_ref:出現在要連結多個表的查詢計劃中,驅動表迴圈獲取資料,這行資料是第二個表的主鍵或者唯一索引,作為條件查詢只返回

一條資料,且必須為not null,唯一索引和主鍵是多列時,所有的列都用作比較時才會出現eq_ref

ref:不像eq_ref那樣要求連結順序,也沒有主鍵和唯一索引的要求,只要使用相等條件檢索時就可能出現,常見與服務索引的等值查詢或者多列主鍵、唯一索引中,使用第一個列之外的列作為等值查詢也會出現,總之,返回資料不唯一的等值查詢就可能出現

fulltext:全文索引檢索,全文索引的優先順序很高,若全文索引和普通索引同時存在時,mysql不管代價,優先選擇使用全文索引

ref_on_null:與ref方法類似,只是增加了null值的比較,實際用的不多

unique_subquery:用於where中的in形式子查詢,子查詢返回不重複唯一值

index_subquery:用於in形式子查詢使用到了輔助索引或者in常數列表,子查詢可能返回重複值,可以使用索引將子查詢去重

range:索引範圍掃描,常見於使用>,<is null,between,in,like等運算子的查詢中

index_merge:標識查詢使用了兩個以上的索引,最後取交際或者並集,常見and,or的條件使用了不同的索引,官方排序這個ref_or_null之後,但是實際上由於要取多個索引,效能可能大部分時間不如range

index:索引全表掃描,把索引從頭到尾掃一遍,常見於使用索引列就可以處理不需要讀取資料檔案的查詢,可以使用索引排序或者分組查詢

all:這個就是全表掃描資料檔案,然後再在server層進行過濾返回符合要求的記錄

 

type列總結

依次效能從好到差:system,const,eq_ref,ref,fulltext,ref_or_null,unique_subquery,index,subquery,range,index_merge,index,ALL,除了all之外,其他的type都已使用到索引,除了index_merge之外,取它的type只可以用到一個索引,好的sql查詢至少要達到range級別,最好要達到ref級別

 

#possible_key列

查詢可能使用到的索引

 

#key

查詢真正使用到的索引

 

#key_len列

用於處理查詢的索引長度,如果是單列索引,那就是整個索引長度,如果是多列索引,那麼查詢不一定都能使用到所有的列,具體使用到了多少個列索引,這裡就會計算機進去,沒有使用的列不會計算進去,留意下這個列的值,算一下你的多列索引總長度就知道有沒有使用到所有列了,另外,key_len自己算where條件用到的索引長度,而排序和分組就算用到了索引,也不會計算到key_len中

 

#ref列

如果是使用的常數等值查詢,這裡會顯示const,如果是連線查詢,被驅動表的執行計劃這裡會顯示驅動表的關聯欄位,如果是條件使用了表示式或者函式,或者條件列發生了內部隱式轉換,這裡可能顯示為func

 

#row列

這裡是執行計劃中估算的掃描行數,不是精確數值

 

#extra列

no table used:不帶from字句的查詢或者From dual查詢

NULL:查詢的列未被索引覆蓋,並且where篩選條件是索引的前導列,意味著用到了索引,但是部分欄位未被索引覆蓋,必須通過“回表”來實現,不是純粹地用到了索引,也不是完全沒用到索引

Using where Using index:查詢的列被索引覆蓋,並且where篩選條件是索引列,但是不是索引的前導列,意味著無法直接通過索引查詢來查詢到符合條件的資料

Using index condition:與Using where類似,查詢的列不完全被索引覆蓋,where條件中是一個前導列的範圍

Using temporary:標識使用了臨時表儲存中間結果。臨時表可以是記憶體臨時表和磁碟臨時表,執行計劃中看不出來,需要檢視status變數,used_tmp_table,used_tmp_disk_table才能看出來

Using filesort:mysql會對結果使用一個外部索引排序,而不是按索引次序從表裡讀取行,此時mysql會根據聯接型別瀏覽所有符合條件的記錄,並儲存排序關鍵字和行指標,然後排序關鍵字並按順序檢索資訊,這種情況下一般也是要考慮使用索引優化

Using intersect:表示使用and的各個索引的條件,該資訊表示從處理結果獲得交集

Using union:表示使用or連線各個使用索引的條件時候,該資訊表示從處理結果獲取並集

Using sort_union和Using sort_intersection:用and和or查詢資訊量大時,先查詢主鍵,然後進行排序合併後返回結果集

Fistnatcg(tb_name):5.6.X開始引入的優化子查詢的新特性之一,常見於where字句含有in()型別的子查詢,如果表內的資料量比較大,就可能出現這個

Loosescan(m...n):5.6.x之後引入的優化子查詢的新特性之一,在in()型別的子查詢中,子查詢返回的可能有重複記錄時,就可能出現這個

 

#filtered列

使用explain extended時會出現這個列,5.7之後的版本預設就有了這個欄位,不需要使用explain extended了,這個欄位表示儲存引擎返回的資料在server層過濾後,剩下多少滿足條件的查詢記錄資料量的比例,注意是百分比,不是具體記錄數

 

#join_buffer_size

mysql連線緩衝區的大小,這個是在關聯時候必不可少的,主要是控制關聯時候載入驅動表的資料進入到緩衝區大小,如果緩衝區開闢的越大,說明儲存的表偏移量資料越多,查詢效率越快

 

 

#緩衝區處理零時臨時處理資料的大小

show rariables like '%sort_buffer_size%';

 

#二次讀取緩衝區的大小

show rariables like '%read_rnd_buffer_size%';

相關文章