1. 程式人生 > >使用explain分析及優化由多表(三個以上)組成的檢視效能

使用explain分析及優化由多表(三個以上)組成的檢視效能

檢視如下圖:


create or replace view FLOW_SUBMITPROCESS_V as 

select pi.START_USER_ID_,pir.STARTUSERID,pi.PROC_INST_ID_,pir.PROCESSINSTID,pir.CURRENTTASKINSTID as TASKID,pir.PROCESSSTARTER as SUBMITUSERJSON_,ta.NAME_

from ACT_HI_TASKINST ta,ACT_HI_PROCINST pi,FLOW_PROCESSINST_RELA pir

where ta.ID_=pir.CURRENTTASKINSTID and

 pi.PROC_INST_ID_=pir.PROCESSINSTID;

1、使用從表索引欄位作為查詢條件

用從表的一個欄位作為查詢條件(從表中的這個欄位已經是索引欄位),從下圖的效果可以看到,type中有一個ALL,全表檢索,證明從表的索引欄位對查詢並沒有幫助


將查詢欄位換成使用主表的StartUserID (這個欄位是索引欄位)


2、使用檢視中與主表關聯的欄位查詢的效能
下圖,查詢的欄位與主表的主鍵PROCESSINSTID相關聯,效率依然是有一個全表檢索

使用主表的主鍵欄位進行查詢,則效能有所優化


總結:
1、建立多表(三個表或以上)關聯檢視時,如果是主表和副表都有的欄位,儘量使用主表的欄位(特別是主表的主鍵)
2、副表的欄位(無論是普通欄位還是主鍵、索引欄位)作為查詢條件對查詢都沒有幫助,都需進行全表檢索


explain各個屬性的含義 

id 

select查詢的序列號 

select_type 

select查詢的型別,主要是區別普通查詢和聯合查詢、子查詢之類的複雜查詢。 

table 

輸出的行出自哪張的表。 

type 

重要的效能指標,聯合查詢所使用的型別。 

type顯示的是訪問型別,是較為重要的一個指標,結果值從好到壞依次是: 

system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL 

System(表中僅有一行,即常量表), 

const(單表中最多有一個匹配行), 

eq_ref(對於前面的每一行,在此表中只查詢一條記錄), 

ref(使用普通的索引), 

ref_or_null(ref類似,但是條件中包含對於NULL查詢)

index_merge(索引合併優化)

unique_subquery(in的後面是一個查詢主鍵欄位的子查詢)

index_subquery(類似unique_subquery,主要是in的後面是查詢非唯一索引欄位的子查詢)range(單表中的範圍查詢)

index(對於當前的每一行,都通過查詢索引來得到資料)

all(對於當前的每一行,都通過全表掃描來得到資料))

一般來說,得保證查詢至少達到range級別,最好能達到ref

possible_keys 

指出MySQL能使用哪個索引在該表中找到行。如果是空的,沒有相關的索引。這時要提高效能,可通過檢驗WHERE子句,看是否引用某些欄位,或者檢查欄位不是適合索引。 

key 

顯示MySQL實際決定使用的鍵。如果沒有索引被選擇,鍵是NULL。 

key_len 

顯示MySQL決定使用的鍵長度。如果鍵是NULL,長度就是NULL。文件提示特別注意這個值可以得出一個多重主鍵裡mysql實際使用了哪一部分。 

ref 

顯示哪個欄位或常數與key一起被使用。 

rows 

這個數表示mysql要遍歷多少資料才能找到,在innodb上是不準確的。 

Extra 

Distinct 一旦MYSQL找到了與行相聯合匹配的行,就不再搜尋了

Not exists MYSQL優化了LEFT JOIN,一旦它找到了匹配LEFT JOIN標準的行,就不再搜尋了

Range checked for eachRecordindex map:#)沒有找到理想的索引,因此對於從前面表中來的每一個行組合,MYSQL檢查使用哪個索引,並用它來從表中返回行。這是使用索引的最慢的連線之一

Using filesort 看到這個的時候,查詢就需要優化了。MYSQL需要進行額外的步驟來發現如何對返回的行排序。它根據連線型別以及儲存排序鍵值和匹配條件的全部行的行指標來排序全部行

Using index 列資料是從僅僅使用了索引中的資訊而沒有讀取實際的行動的表返回的,這發生在對錶的全部的請求列都是同一個索引的部分的時候

Using temporary 看到這個的時候,查詢需要優化了。這裡,MYSQL需要建立一個臨時表來儲存結果,這通常發生在對不同的列集進行ORDER BY上,而不是GROUP BY

Using Where  使用了WHERE從句來限制哪些行將與下一張表匹配或者是返回給使用者。如果不想返回表中的全部行,並且連線型別ALLindex,這就會發生,或者是查詢有問題

如果此資訊顯示Using filesort或者Using temporary的話會很吃力,WHEREORDER BY的索引經常無法兼顧,如果按照WHERE來確定索引,那麼在ORDER BY時,就必然會引起Using filesort,這就要看是先過濾再排序划算,還是先排序再過濾划算。