目錄
- 總體架構
- 一. 連接器
- 二、 查詢快取
- 三、分析器
- 四、 優化器
- 五、 執行器
總體架構

一. 連接器
??連接器主要負責跟客戶端建立連接、權限驗證和管理連接,可以使用命令show processlist查看連接資訊,當一個用戶連接創建成功之后,權限資訊就已經讀入記憶體,之后再修改該用戶的權限,如果不重繪的話,則無法生效,
??對于一個連接,如果長時間沒有收到指令(處于空閑狀態),那么達到一定的時間之后,連接器會斷開這個鏈接,這個時間由引數wait_timeout控制,默認為8小時,
??連接器中的連接分為長連接和短連接:
- 長連接:連接成功后,客戶端請求使用同一個連接
- 短連接:每次執行完請求后會斷開連接,再有請求會重新建立連接
??由于在平時我們一般為了避免頻繁反復創建連接的開銷,都是使用的長連接,也就是長期維持一個連接不斷開,但是要注意,一個連接管理了其在使用程序中占用的一些記憶體,會在連接斷開的時候隨連接一起釋放,如果連接不斷開,長期不處理一直堆積,則可能導致記憶體占用過大,被系統強殺,一般有兩個解決方案:
- 定期斷開長連接,每隔一段時間或執行一個占用大量記憶體的查詢之后斷開連接,從而釋放記憶體,當需要查詢的時候再重新創建連接
- 5.7之后的版本可以使用mysql_reset_connection來重新初始化連接資源,不需要重新連接和權限驗證,而將連接恢復到新建時的狀態,同時也會有一些其它影響,比如釋放表鎖、清除臨時表、重置會話中設定的變數等等
二、 查詢快取
注:查詢快取8.0 版本后被廢除
??連接創建成功之后就可以執行SQL陳述句了,不過如果開啟了查詢快取,那么在真正分析SQL之前會先從快取中查詢,如果快取命中則直接回傳,查詢快取就是一個Key-Value結構,Key是SQL陳述句,Value是對應的查詢結果,如果快取未命中,就會繼續后面的查詢操作,查詢完成之后,會把結果存入查詢快取中,
??為什么查詢快取會被洗掉呢?因為查詢快取通常弊大于利,如果對一個表進行更新,那么這個表對應的查詢快取都會被清空,對于經常更新的表,查詢快取的失效會非常頻繁,基本就不起作用,而且還有更新快取的開銷,對于那種基本會保持不變的資料表,倒是可以選擇使用查詢快取,比如系統配置表等,這種表的快取命中率會高些,可能能做到利大于弊,不過對于這種配置,我們還可以使用外部快取,
??通過引數query_cache_type可以配置查詢快取,該引數有3個可選值,分別為:
- 0:關閉查詢快取
- 1:開啟查詢快取
- 2:當SQL中有SQL_CACHE關鍵詞時使用查詢快取,比如select SQL_CACHE * from t where xxx;
三、分析器
??如果查詢快取沒有命中,那么SQL就需要真正得到執行,在執行之前需要對SQL進行決議,這個決議主要分為詞法分析和語法分析兩個步驟,
- 詞法分析:從SQL中提取關鍵詞,比如select 、from、表名、欄位名等等
- 語法分析:根據詞法分析的結果和MySQL定義的一些語法規則檢查SQL語法是否合法,最侄訓生成一顆抽象語法樹(AST)
四、 優化器
??優化器以分析器生成的AST為輸入,對SQL進行優化,生成優化器認為的最優執行方案,交給執行器執行,優化程序包括SQL的邏輯轉換和代價計算,
??邏輯轉化就類似于Java的靜態編譯期優化,會對SQL進行一些"簡化",保證SQL轉換前后執行結果一致,比如,where 1=1 and a.id = 2,可以相當于where a.id = 2,
??代價計算的主要目的是選擇SQL執行的方式,包括是否使用索引、使用哪個索引、多表連接使用什么順序等,代價分為服務層代價和引擎層代價,服務層代價主要是CPU相關,引擎層代價則主要是磁盤I/O相關,MySQL 5.7 引入了兩個系統表mysql.server_cost和mysql.engine_cost來配置這兩種代價,表中配置的就是各種操作對應的代價,比如臨時表創建、排序、頁讀取等等,
??優化器會根據生成的查詢計劃和上述兩種代價配置來計算一個查詢計劃的最終代價,在多個查詢計劃中選擇代價最小的那一個交給執行器執行,但是要注意,代價最小,有時候并不一定代表執行時間就最短,
五、 執行器
??執行器會根據優化器選擇的查詢計劃去執行SQL,執行之前還會校驗請求用戶是否擁有對應的查詢權限,最終呼叫MySQL引擎層提供的介面,執行SQL陳述句并且回傳結果,如果開啟了查詢快取,結果還會存盤在查詢快取中,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/272215.html
標籤:其他
上一篇:自定義組件-微信小程式
