MySQL優化---常見的性能瓶頸以及Explain詳解

一、MySQL常見性能瓶頸

CPU方面:SQL中對大量數據進行比較、關聯、排序、分組。

IO方面:實際內存滿足不了緩存數據或排序等需要,導致產生大量的物理I/O操作。

鎖:不適宜的鎖設置,導致線程阻塞性能下降。死鎖,線程之間交叉調用資源導致死鎖,程序卡住。

服務器硬件的性能瓶頸:可以通過top free iostat 和 vmstat來查看系統的性能狀態。

二、Explain

1.Explain是什麼?

使用EXPLAIN關鍵字可以模擬優化器執行SQL查詢語句,從而知道MySQL是如何處理你的SQL語句的。分析你的查詢語句或是表結構的性能瓶頸

2.怎麼用?

Explain + SQL語句

執行計劃包含的信息

1)id:select查詢的序列號,包含一組數字,表示查詢中執行select子句或操作表的順序
①如果id相同,執行順序由上至下  
此例中 先執行where 後的第一條語句 t1.id = t2.id 通過 t1.id 關聯 t2.id 。 而  t2.id 的結果建立在 t2.id=t3.id 的基礎之上。
 
 

②如果id不同,id值越大其執行優先級越高,越先被執行

③id相同和id不同的情況同時存在

id如果相同,可以認爲是一組,從上往下順序執行;
在所有組中,id值越大,優先級越高,越先執行

衍生表 = derived2 --> derived + 2 (2 表示由 id =2 的查詢衍生出來的表。type 肯定是 all ,因爲衍生的表沒有建立索引)

2)select_type:表示查詢的類型,主要是用於區別普通查詢、聯合查詢、子查詢等複雜查詢。

①SIMPLE:簡單的select查詢,查詢中不包含子查詢或者UNION。

②PRIMARY:查詢中若包含任何的複雜查詢,最外層查詢則被標記爲PRIMARY。

③DERIVED:在from列表中包含的子查詢被標記爲DERIVED(衍生),MySQL會遞歸執行這些子查詢,把結果放在臨時表裏。

④SUBQUERY:在select或where列表中包含了子查詢,且結果爲一個值

⑤DEPENDENT SUBQUERY:在select或where列表中包含了子查詢,且結果爲多值。

⑥UNCACHEABLE SUBQUERY:無法被緩存的子查詢

 @@爲環境參數,所以無法緩存。

⑦UNION:若第二個SELECT出現在UNION之後,則被標記爲UNION,若UNION包含在from子句的子查詢中,外層select將被標記爲:DERIVED

⑧UNION RESULT:從UNIOIN中獲取結果的表

3)table:顯示這一行的數據是關於哪張表的。

4)type: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都是讀全表,但index是從索引中讀取的,而all是從硬盤中讀的

all:將通過遍歷硬盤上的全表數據進行查找。效率最低

5)possible_keys:顯示可能應用在這張表中的索引,一個或多個。查詢涉及到的字段上若存在索引,則該索引將被列出,但不一定被查詢實際使用

6)key:該查詢真正使用到的索引,如果爲null,則沒有使用索引。且如果出現覆蓋索引的情況,即當查詢具體某一字段時,且那個字段有索引時,key 值會顯示爲索引。不懂看下圖

7)key_len:表示索引中使用的字節數,key_len越大表明用到的索引越多,性能越好

8)ref:顯示索引的哪一列被使用了。

emp這張表用了常量查詢,dept這張表查詢時用到了mytest數據庫下的emp表的deptno索引。

9)rows:rows列顯示MySQL認爲優化器執行查詢時必須檢查的行數。越小越好。

10)包含不適合在其他列,但非常重要的信息 Extra

Using filesort:該字段出現,不是好事!!!說明mysql會對數據使用一個外部的索引排序,而不是按照表內的索引順序進行讀取。MySQL中無法利用索引完成的排序操作稱爲“文件排序”。

出現filesort的情況:

 
優化後,不再出現filesort的情況:(給 ename 加上了索引)

 
查詢中排序的字段,排序字段若通過索引去訪問將大大提高排序速度
Using temporary:更不是什麼好事。。使了用臨時表保存中間結果,MySQL在對查詢結果排序時使用臨時表。常見於排序 order by 和分組查詢 group by。如何優化?儘量group by 和 order by 的時候用索引字段,如果爲複合索引需要將索引全用上。。

Using Index:這是好事!!表明相應的select操作中使用了覆蓋索引,也就是說,直接在索引中進行查找。覆蓋索引的意思是:假如建立了一個複合索引(col1,col2,col3),在查詢的字段中如果是其子集,則會直接從索引文件中查找,不需要去數據文件中查找了。

當與 Using where 同時出現的時候,表明索引也被用來執行查找操作了。

④Using where:表明使用了where過濾

⑤Using join buffer:使用了連接緩存

⑥impossible where:where子句的值總是false,不能用來獲取任何元組

⑦select tables optimized away

在沒有GROUPBY子句的情況下,基於索引優化MIN/MAX操作或者對於MyISAM存儲引擎優化COUNT(*)操作,不必等到執行階段再進行計算,查詢執行計劃生成的階段即完成優化。

在inoodb中

在Myisam中

myisam 中會維護 總行數 (還有其他參數)這個參數,所以在執行查詢時不會進行全表掃描。而是直接讀取這個數。
但會對增刪產生一定的影響。根據業務情況決定誰好誰壞
innodb 中沒有這個機制。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章