MySQL基礎(八):性能分析(主要用於SQL查詢語句優化)

下面是小凰凰的簡介,看下吧!
💗人生態度:珍惜時間,渴望學習,熱愛音樂,把握命運,享受生活
💗學習技能:網絡 -> 雲計算運維 -> python全棧( 當前正在學習中)
💗您的點贊、收藏、關注是對博主創作的最大鼓勵,在此謝過!
有相關技能問題可以寫在下方評論區,我們一起學習,一起進步。
後期會不斷更新python全棧學習筆記,秉着質量博文爲原則,寫好每一篇博文。

一、MySQL常見瓶頸

1. cpu
SQL中對大量數據進行比較、關聯、排序、分組,其中最大的壓力在於'比較' 
2. IO
實例內存滿足不了緩存數據或排序等需要,導致產生大量 物理 IO。使用交換內存
查詢執行效率低,掃描過多數據行。
3. 鎖
不適宜的鎖的設置,導致線程阻塞,性能下降。
死鎖,線程之間交叉調用資源,導致死鎖,程序卡住。
4. 服務器硬件的性能瓶頸
top,free, iostat和vmstat來查看系統的性能狀態

Linux服務器硬件性能查看詳解:https://blog.csdn.net/weixin_44571270/article/details/104883887

二、explain關鍵字

1、explain是什麼?

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

2、explain能幹嘛?

  • 表的讀取順序
  • 哪些索引可以使用
  • 數據讀取操作的操作類型
  • 哪些索引被實際使用
  • 表之間的引用
  • 每張表有多少行被優化器查詢

是不是看完一臉懵逼😄?很正常,請先往下看,小凰凰喊你回頭看,你再回頭來看這個,你就茅塞頓開了😯!

3、explain怎麼用?

# 使用方法
Explain + SQL語句

執行計劃包含的信息:
在這裏插入圖片描述
接下來我們就要對上面的信息逐一分析!這上面的信息也是你和麪試官諞SQL優化的主要內容!其中重點內容是id、type、key、rows、Extra!

4、各字段的解釋

(1)id

select查詢的序列號,包含一組數字,表示查詢中執行select子句或操作表的順序

  • id相同,執行順序由上至下
    在這裏插入圖片描述id相同,執行順序由上至下
    此例中 先執行where 後的第一條語句 t1.id = t2.id 通過 t1.id 關聯 t2.id 。 而 t2.id 的結果建立在 t2.id=t3.id 的基礎之上。

  • id不同,如果是子查詢,id的序號會遞增,id值越大優先級越高,越先被執行
    在這裏插入圖片描述id 不同,如果是子查詢, id 的序號會遞增, id 值越大優先級越高,越先被執行

  • id相同不同,同時存在
    在這裏插入圖片描述id如果相同,可以認爲是一組,從上往下順序執行
    不同的話,id值越大,優先級越高,越先執行
    衍生表 = derived2 --> derived + 2 (2 表示由 id =2 的查詢衍生出來的表。type 肯定是 all ,因爲衍生的表沒有建立索引)

(2)select_type

既然叫select_type(查詢類型),那麼有哪些類型?它又是用來幹什麼的呢?

# 用來幹什麼?
主要是用於區別普通查詢、聯合查詢、子查詢等的複雜查詢

有哪些類型呢?

  1. SIMPLE
    釋義:簡單的 select 查詢,查詢中不包含子查詢或者UNION

    例如:
    在這裏插入圖片描述

  2. PRIMARY
    釋義:查詢中若包含任何複雜的子部分,最外層查詢則被標記爲Primary

    例如:
    在這裏插入圖片描述

  3. DERIVED
    釋義:在FROM某個表中包含的子查詢被標記爲DERIVED(衍生) ,MySQL會遞歸執行這些子查詢, 把結果放在臨時表裏。

    例如:
    在這裏插入圖片描述from a表,其中包含的子查詢(id=2)select_type被標記爲DERIVED,遞歸執行select t1.content from t1,把結果放在臨時表a

  4. SUBQUERY
    釋義:在SELECT或WHERE列表中包含了子查詢

    例如:
    在這裏插入圖片描述

  5. UNION
    釋義:若第二個SELECT出現在UNION之後,則被標記爲UNION; 若UNION包含在FROM子句的子查詢中,外層SELECT將被標記爲:DERIVED

    例如:
    在這裏插入圖片描述

  6. UNION RESULT
    釋義:從UNION表獲取結果的SELECT

    例如:
    在這裏插入圖片描述

(3)table

顯示這一行的數據是關於哪張表的

(4)type
type顯示的是訪問類型,是較爲重要的一個指標,其值從最好到最壞依次是 : 

system>const>eq_ref>ref>range(儘量保證)>index>ALL 
 
 一般來說,得保證查詢至少達到range級別,最好能達到ref。 

下面我們對type的每個值進行深入解讀:

  • 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快,因爲索引文件通常比數據文件小。 (也就是說雖然all和Index都是讀全表,但index是從索引中讀取的,而all是從硬盤中讀的)

    例如:
    在這裏插入圖片描述

  • all
    釋義:Full Table Scan,將遍歷全表以找到匹配的行,沒有索引

(5)possible-keys

顯示該查詢可能會用到的索引。 查詢涉及到的字段上若存在索引,則該索引將被列出,但不一定被查詢實際使用

(6)key

實際使用的索引。如果爲NULL,則沒有使用索引。

就像我請客,準備請的人是100人,這個就像是possible keys
但是實際來的人大於、小於、等於這都是又可能的,這個就像是key

例如:
在這裏插入圖片描述

(7)key_len

表示索引中使用的字節數,可通過該列計算查詢中使用的索引的長度。在不損失精確度的情況下,長度越短越好
在這裏插入圖片描述上圖中第一個查詢相比第二個查詢,兩個限制條件,精確度高,因此key_len大,耗費高!

key_len顯示的值爲索引字段的最大可能長度,並非實際使用長度,key_len是根據表定義計算得到的,不是通過表內檢索出的!你可以簡單理解爲key_len就是得到一個查詢結果,根據表定義計算而出的一個索引成本!因此滿足要求的情況下,key_len應該儘量的小!

注:若key爲NULL,那麼key_len一定也爲NULL!因爲key_len爲索引成本,索引都沒有談何成本

(8)ref

顯示索引的哪一列被使用了,如果可能的話,是一個常數。哪些列或常量被用於查找索引列上的值
在這裏插入圖片描述注意:

1. 這裏t1是主表哈,t2是外鍵關聯的表,就像員工表關聯部門表一樣!
2. 我們先看`t1.col1 = t2.col1`,因爲t1表它引用了t2表的col1字段,因此ref爲shared.t2.col1(`shared庫下t2表下的col1字段`3. t1.col2 = 'ac',因爲它直接就等於一個固定的量,因此ref爲const常數

注意:key如果爲NULL,那麼ref必定爲NULL,因爲它是顯示索引的哪一列被使用了!

(9)rows

rows列顯示MySQL認爲它執行查詢時必須檢查的行數。越少越好
在這裏插入圖片描述上圖我們只關注t2表就行了,第一個查詢語句,t2表查詢行數爲640行,索引也沒用,第二個語句我們爲它創建了一個col1和col2的複合索引,第三個查詢語句t2表用到了索引,rows減到了142行!

沒有索引你就需要全表掃描,檢查行數當然多!

好,到此爲止,你就可以回頭看剛纔那個我讓各位小夥伴忽略的內容了,相信你肯定能看懂!

(10)Extra

Extra(額外的),其中包含不適合在其他列中顯示但十分重要的額外信息

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

    出現filesort的情況:
    在這裏插入圖片描述
    索引常用於查詢或排序,col1=‘ac’,用到了部分索引col1,因爲我們這裏是個複合索引嘛(indx_col1_col2_col3),ref=const,說明col1確實用到了索引,因此問題就出在 order by col3,你看下面哪一個查詢語句,就沒有using filesort,這是爲什麼?

看下里面的創建索引的情況:https://blog.csdn.net/weixin_44571270/article/details/106972583

我們把複合索引(indx_col1_col2_col3)比作三層樓
第一個查詢語句只使用了col1和col3索引,col2索引沒有使用,相當於就是二樓斷開了,因此無法直接使用複合索引,因此mysql就會use filesort!
第二個查詢語句col1、col2、col3都使用了,因此好着的!
  • Using temporary
    釋義:使了用臨時表保存中間結果,MySQL在對查詢結果排序時使用臨時表。常見於排序 order by 和分組查詢 group by。
    在這裏插入圖片描述

  • Using join buffer
    釋義:使用了連接緩存
    當你使用左連接、右連接、內連接、或者聯表查詢時都有可能出現出現!
    在這裏插入圖片描述出現在當兩個表連接時
    驅動表(被連接的表、left join 左邊的表、right join右邊的表、inner join 中數據少的表) 沒有索引的情況下。如上圖就是被連接的表沒有索引的情況!
    給驅動表建立索引可解決此問題。且 type 將改變成 ref

  • Using index
    表示相應的select操作中使用了覆蓋索引(Covering Index),避免訪問了表的數據行,效率不錯! 如果同時出現using where,表明索引被用來執行索引鍵值的查找; 如果沒有同時出現using where,表明索引只是用來讀取數據而非利用索引執行查找。

  • Using where
    表明使用了where過濾

  • impossible where
    where子句的值總是false,不能用來獲取任何元組
    在這裏插入圖片描述不可能一個人的名字既叫july又叫z3吧!因此impossible where

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

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

5、實戰訓練

求出下面的sql語句的執行順序!
在這裏插入圖片描述執行順序解析:
在這裏插入圖片描述執行順序答案:

select name,id from t2
	👇
select id,name from t1 where other_column=""
	👇
select id from t3
	👇
select d1,name ...
	👇
兩個結果union操作
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章