「MySQL」 MySQL執行流程

天澄發表於2019-02-21

MySQL知識梳理圖,一圖看完整篇文章:

「MySQL」 MySQL執行流程

MySQL優化一直是老生常談的問題,尤其在面試環節中,但在做MySQL的優化之前,得先了解MySQL的執行流程是怎樣,這樣才更好的去優化。

面試過程中也通常會問如果高併發或者使用者反映系統太卡,我們該怎麼去優化?

  • 如果高併發,請求書過多,優先增加web伺服器機器,做好負載均衡。
  • 如果請求靜態頁面不卡,但是動態資料卡,則說明MySQL處理的請求過多,需要再MySQL的上游封裝一層快取層,減輕MySQL的壓力。
  • 資料庫層其實是非常脆弱的一層,一般在應用架構設計時,通常需要將一些使用者非實時的資料或變化不頻繁的資料快取起來,讓這些請求穿透不到DB,同時還可以引入佇列做資料的非同步更新。如果請求數激增,還是有非常大的查詢壓力到MySQL,這時候則想辦法解決MySQL的瓶頸。

1. 執行流程圖

簡易的流程圖如下:

「MySQL」 MySQL執行流程

大致流程描述:

  • MySQL客戶端通過協議將SQL語句傳送給MySQL伺服器。
  • 伺服器會先檢查查詢快取中是否有執行過這條SQL,如果命中快取,則將結果返回,否則進入下一個環節(查詢快取預設不開啟)。
  • 伺服器端進行SQL解析,預處理,然後由查詢優化器生成對應的執行計劃。
  • 伺服器根據查詢優化器給出的執行計劃,再呼叫儲存引擎的API執行查詢。
  • 將結果返回給客戶端,如果開啟查詢快取,則會備份一份到查詢快取中。

2. 流程圖詳解

2.1 查詢快取

MySQL查詢快取會儲存查詢返回的完整結構。當查詢命中該快取時,MySQL會立刻返回結果,跳過了解析、優化和執行階段。 但查詢快取是預設不開啟的,且要求SQL和引數都是一樣,同時查詢快取系統會跟蹤查詢中涉及的每一個表,如果這些表發生變化,則該表相關的所有快取資料均會失效。所以命中率一般較低,生產環境中也很少用到,具體流程就不描述了。如果感興趣的可以查閱詳細資料。

2.2 解析和預處理

如果查詢快取未命中,則到解析器。解析器主要是對SQL語句進行解析,使用MySQLy語法規則進行驗證和解析查詢,並生成對應的解析樹。 得到解析數之後,還需要做預處理,預處理則進一步檢查解釋樹是否合法,以及進行一些優化,比如檢查資料表和列是否存在,如果有計算,會將計算的結果算出來等等。

2.3 查詢優化器

查詢優化器是整個流程中重要的一環。查詢優化器會將預處理之後的解析樹轉化成執行計劃。一條查詢可以有多種執行方法,最後均會返回相同結果。查詢優化器的作用就是找到這其中最好的執行計劃。   生成執行計劃的過程會消耗較多的時間,特別是存在許多可選的執行計劃時。如果在一條SQL語句執行的過程中將該語句對應的最終執行計劃進行快取,當相似的語句再次被輸入伺服器時,就可以直接使用已快取的執行計劃,從而跳過SQL語句生成執行計劃的整個過程,進而可以提高語句的執行速度。 通常所講的優化SQL,其實就是想讓查詢優化器,按照我們的思路,幫我們選擇最優的執行方案。

2.4 查詢執行計劃

查詢執行計劃,就是MySQL查詢中的執行計劃,比如是執行where語句還是from語句,下面有一張執行順序的圖。

「MySQL」 MySQL執行流程

最先執行的總是FROM操作,最後執行的是LIMIT操作。其中每一個操作都會產生一張虛擬的表,這個虛擬的表作為一個處理的輸入,只是這些虛擬的表對使用者來說是透明的,但是隻有最後一個虛擬的表才會被作為結果返回。如果沒有在語句中指定某一個子句,那麼將會跳過相應的步驟。

  • FORM: 對FROM的左邊的表和右邊的表計算笛卡爾積。產生虛表VT1
  • ON: 對虛表VT1進行ON篩選,只有那些符合的行才會被記錄在虛表VT2中。
  • JOIN: 如果指定了OUTER JOIN(比如left join、 right join),那麼保留表中未匹配的行就會作為外部行新增到虛擬表VT2中,產生虛擬表VT3, 如果 from子句中包含兩個以上的表的話,那麼就會對上一個join連線產生的結果VT3和下一個表重複執行步驟1~3這三個步驟,一直到處理完所有的表為止。
  • WHERE: 對虛擬表VT3進行WHERE條件過濾。只有符合的記錄才會被插入到虛擬表VT4中。
  • GROUP BY: 根據group by子句中的列,對VT4中的記錄進行分組操作,產生VT5.
  • CUBE | ROLLUP: 對錶VT5進行cube或者rollup操作,產生表VT6.
  • HAVING: 對虛擬表VT6應用having過濾,只有符合的記錄才會被 插入到虛擬表VT7中。
  • SELECT: 執行select操作,選擇指定的列,插入到虛擬表VT8中。
  • DISTINCT: 對VT8中的記錄進行去重。產生虛擬表VT9.
  • ORDER BY: 將虛擬表VT9中的記錄按照<order_by_list>進行排序操作,產生虛擬表VT10.
  • LIMIT:取出指定行的記錄,產生虛擬表VT11, 並將結果返回。

2.5 查詢執行引擎

執行計劃會傳給查詢執行引擎,執行引擎選擇儲存引擎來執行計劃,到磁碟中的檔案中去查詢。 影響這個查詢效能最根本的原因是什麼? 其實是硬碟的機械運動,也就是我們平時熟悉的IO,所以一條查詢語句是快還是慢,就是根據這個時間的IO來確定的。那怎麼執行IO又是什麼來確定的?就是傳過來的這一份執行計劃.

更多文章請關注公眾號 『天澄技術雜談』

「MySQL」 MySQL執行流程

參考文章:

  https://juejin.im/post/5b7036de6fb9a009c40997eb
  https://blog.csdn.net/I980663737/article/details/78421523
  https://www.cnblogs.com/rollenholt/p/3776923.html
複製程式碼

相關文章