一文搞懂MySQL基礎框架

看了《MySQL高性能》以及幾位博客大佬的博客。概要總結一下自己的理解。


先給出MySQL基本框架示意圖,這張圖的風格很喜歡,目前還不知道用什麼畫出來的,先用一下

在這裏插入圖片描述

咋一看圖好像有點複雜,好像亂七八糟的。

不慌不慌,我們慢慢來,保證這篇看完就立馬能大致全部瞭解了。

在這裏插入圖片描述

一般可以把MySQL分爲Server層和存儲引擎層兩部分。

這一篇主要把Server層給弄清楚就可。

  • Server層:包含了連接器、查詢緩存、分析器、優化器、執行器等,這裏涵蓋了MySQL的大多數核心功能區以及所有的內置函數。

    • 內置函數:日期,時間,數學和加密函數等;
    • 所有的跨存儲引擎的功能都在這一層實現:存儲過程、觸發器、視圖等。
  • 存儲引擎層:負責着數據的存儲和提取,並提供了讀寫接口。不同的引擎有着各自的方式。

    • create table時如果不指定引擎類型,默認使用的就是InnoDB。

接下來就是server層了。

一、連接器

功能就是負責跟客戶端建立連接,獲取權限,維持和管理連接。我們可以通過這個連接器呢,把客戶端和server層連接起來,從而登錄到mysql。

  • 連接過程
    • 經典的TCP握手之後,服務器會開始驗證身份。這個時候要用到我們輸入的用戶名和密碼
    • 用戶名密碼正確,連接器就會回到權限表裏找到我們所擁有的權限。之後在這個連接面裏的權限判斷邏輯,都會依賴於此時讀到的權限。
  • 連接完成之後
    • 如果不進行後續操作,這個連接就會空閒下來。可以使用show processlist命令來查看它。
    • 若很長時間都沒有動靜,那麼連接器就會自動斷開,這個時間默認的是8小時,是由wait_timeout控制的。

報告:我想修改wait_timeout時間,八小時太短了,滿足不了我。

在這裏插入圖片描述

雖然很詫異,但是這是沒有問題的啦

wait_timeout這個當然是可以手動更改的,更改方法如下

show global variables like 'wait_timeout'; -- 可查看當前wait_timeout時間爲多少;
set global wait_timeout=36000; -- 修改wait_timeout爲36000;
-- 當然咱們有圖有真相。

在這裏插入圖片描述

關於上述的連接過程中連接器需要讀的部分權限表

在這裏插入圖片描述

目前知道的這四個權限表

  • user權限表:記錄允許連接到服務器的用戶帳號信息,裏面的權限是全局級的。

  • db權限表:記錄各個帳號在各個數據庫上的操作權限。

  • table_priv權限表:記錄數據表級的操作權限。

  • columns_priv權限表:記錄數據列級的操作權限。

關於長連接和短鏈接

  • 長連接:指的就是長時間使用同一連接的情況,也就是連接成功後,長時間保持客戶端與服務端的連接狀態。

    可表示爲:

    連接 -> 數據傳輸 -> 保持連接 -> 數據傳輸 -> 保持連接 … -> 關閉連接;

    因此這就需要長連接在沒有數據通信時,定時發送數據包,以維持連接狀態。

  • 短鏈接:在沒有數據傳輸時直接關閉就行了。

    可表示爲:

    連接 -> 數據傳輸 -> 關閉連接;

由於建立連接過程很複雜,所以我們儘量要減少建立連接的動作,也就是儘量使用長連接。

但是呢但是 長連接也存在着一個問題

  • 如果全部使用長連接的話,會發現MySQL佔用內存特別快。

    爲什麼呢?

    • 因爲MySQL在執行的時候臨時使用的內存時管理在連接對象裏面的,這些資源只有在連接斷開的時候會釋放。所以若長連接鏈積累下來,就可能會導致內存佔用太大。然後呢,就會被系統給強制殺死。

    表現出來就是MySQL會異常重啓

    當然也有着解決方案

    • 定期斷開長連接。

    不過如果使用的時MySQL5.7或者更高的版本的話。可以通過執行mysql_reset_connection來重新初始化鏈接資源。好的地方在這個過程不需要重連和重新做權限驗證,而且還會將連接恢復到剛剛創建完時的狀態。妙哉妙哉

查詢緩存

簡介一下:就是之前查詢過的語句被記錄下來了,當你再次使用那個語句時,就不需要進行下面的分析優化執行了,直接在緩存中找即可。

緩存是怎麼被存的呢?

  • 之前執行過的語句以及結果會以key-value對的形式,被直接存放在內存中。key是查詢的語句,value是查詢的結果。

看上去效率可高了呢。。

但其實大多數情況下我們都會不被建議使用查詢緩存。

???爲什麼,明明這麼好用的東西啊

在這裏插入圖片描述

別急別急看這裏 (經過尋找各種大佬博客本蒻j終於找到了答案)

  • 因爲查詢緩存的失效非常的頻繁,只要有對一個表的更新,這個表上的所有查詢緩存都會被清空。這就造成了這麼一種現象:明明你費勁把結果存了起來,結果還沒使用呢,就被一個更新全部清空了。對於頻繁需要更新的數據庫來說,查詢緩存的命中率會非常的低。當然在某些靜態表上,就是很久纔會更新一次的表上,比如一個系統配置表,就比較適合使用查詢緩存。

當不想使用查詢緩存的時候,可以將參數query_cache_type設置成DEMAND。

這之後對於默認的SQL語句都不適用查詢緩存了。當有些你確定要使用查詢緩存的語句,可以用SQL_CACHE顯示指定。比如

select sql_cache * from employee where salary = 3000;

ps:MySQL 8.0版本之後直接就將查詢緩存的整塊功能刪掉了 ,也就是說從8.0開始就徹底沒有這個功能了。

在這裏插入圖片描述

分析器

簡介:如果沒有命中緩存的話,就會開始真正的執行SQL語句了。分析器中簡單的說包含了詞法分析和語法分析。

給個例子分析一下

select * from employee where salary = 3000;
  • 詞法分析:分析器通過語法分析器,識別出了裏面的字符分別是什麼,代表着什麼。

    比如上面例子中,會將select這個關鍵字識別出來,首先知道這是條查詢語句,然後把employee識別成表面employee,再把字符串salary識別成列ID,以此類推。最後識別出每個詞。

  • 語法分析:根據詞法分析的結果,語法分析器會根據語法規則,判斷輸入的這個SQL語句是否滿足MySQL語法。如果發現不滿足,就會收到“you have an error in your SQL syntax”的錯誤提醒。

優化器

簡介:經過上面的分析器,MySQL知道了需要做什麼事兒了,但在開始做之前,還需要經過優化器的處理。

大概兩個優化

  • 優化器在表裏面有多個索引時,決定使用哪個索引。
  • 在一個語句有奪標關聯(join)的時候,決定各個表連接的順序。

選擇更快的索引好理解,稍微有點繞口的時決定各個表連接的順序。

舉個栗子

select * from a join b using(id) where a.c=10 and b.d=20;

這個關聯中

  • 既可以先從表a中取出c=10的記錄的ID值,再根據ID值關聯到表b,再判斷b裏面d的值是否等於20。

  • 也可以先從表b中取出d=20的記錄的ID值,再根據ID值關聯到表a,再判斷a裏面c的值是否等於10。

用不同的執行方法的邏輯結果是一樣的,但是執行的效率會有不同。優化器就會決定選擇使用哪一種方案,當然迴旋執行效率高的。

執行器

簡介:通過分析器知道了我是誰,我要幹什麼,通過優化器知道了我要怎麼幹我乾的事情。於是到了執行器階段,就要開始幹活啦!

當然也不是說幹就幹,人家還是很正經有流程的在這裏插入圖片描述

  • 1、判斷對這個表employee有沒有查詢的權限,如果沒有,那當然不行的了,會返回沒有權限的錯誤❌
  • 2、要是判斷出來有權限呢,就會打開表繼續執行,打開的時候,執行器就會根據表的引擎定義,去使用這個引擎提供的接口。再提一嘴,默認引擎是InnoDB。然後就會順着下去,根據引擎提供的流程,執行下去,最後找到我們想要的。

至此,整個流程就結束了。

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