MySQL基本架構

在講SQL語句是如何執行之前,我想先帶你簡單認識下MySQL的基本架構。

借用一張別人的圖

大體來說,MySQL 可以分為 Server 層和儲存引擎層兩部分。從圖中我們可以看到多個儲存引擎共有一個Server層。

Server層

Server 層包括聯結器、查詢快取、分析器、優化器、執行器等,涵蓋 MySQL 的大多數核心服務功能,以及所有的內建函式(如日期、時間、數學和加密函式等),所有跨儲存引擎的功能都在這一層實現,比如儲存過程、觸發器、檢視等。

什麼叫跨儲存引擎層?可以簡單理解為多張表,因為每張表都可以指定儲存引擎

聯結器

聯結器負責跟客戶端建立連線、獲取許可權、維持和管理連線。連線命令一般是這麼寫的:


mysql -h$ip -P$port -u$user -p

注意:一個使用者成功建立連線後,即使你用管理員賬號對這個使用者的許可權做了修改,也不會影響已經存在連線的許可權。修改完成後,只有再新建的連線才會使用新的許可權設定。

查詢快取

MySQL 8.0 已移除

連線建立完成後,如果你執行的是查詢語句,執行邏輯就會來到第二步:查詢快取。

MySQL 拿到一個查詢請求後,會先到查詢快取看看,之前是不是執行過這條語句。之前執行過的語句及其結果可能會以 key-value 對的形式,被直接快取在記憶體中。key 是查詢的語句,value 是查詢的結果。如果你的查詢能夠直接在這個快取中找到 key,那麼這個 value 就會被直接返回給客戶端。如果語句不在查詢快取中,就會繼續後面的執行階段。

但是由於查詢快取的失效非常頻繁,只要有對一個表的更新,這個表上所有的查詢快取都會被清空。所以不建議使用。這裡也不展開講了。

分析器

如果沒有命中查詢快取,就要開始真正執行語句了。首先,MySQL 需要知道你要做什麼,因此需要對 SQL 語句做解析。

分析器主要有詞法分析和語法分析。一般語法報錯都是在這個階段返回。

優化器

經過了分析器,MySQL 就知道你要做什麼了。在開始執行之前,還要先經過優化器的處理。也就是優化器決定怎麼做。

優化器是在表裡面有多個索引的時候,決定使用哪個索引;或者在一個語句有多表關聯(join)的時候,決定各個表的連線順序。

比如你執行下面這樣的語句,這個語句是執行兩個表的 join:

mysql> select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;

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

這兩種執行方法的邏輯結果是一樣的,但是執行的效率會有不同,而優化器的作用就是決定選擇使用哪一個方案。

執行器

MySQL 通過分析器知道了你要做什麼,通過優化器知道了該怎麼做,於是就進入了執行器階段,開始執行語句。

請注意,這裡會再次判斷是否有相關表的許可權:比如如果有個觸發器,得在執行器階段(過程中)才能確定。如果走的是查詢快取,也會在查詢快取之前校驗相關許可權

許可權校驗通過後,那麼執行器就需要去呼叫相關表的儲存引擎的讀寫介面來獲取結果並返回。

例如對於如下語句

mysql> select * from T where ID=10;

假設表 T 中 ID 欄位沒有索引,那麼執行器的執行流程是這樣的:

  • 呼叫 InnoDB 引擎介面取這個表的第一行,判斷 ID 值是不是 10,如果不是則跳過,如果是則將這行存在結果集中;
  • 呼叫引擎介面取“下一行”,重複相同的判斷邏輯,直到取到這個表的最後一行。
  • 執行器將上述遍歷過程中所有滿足條件的行組成的記錄集作為結果集返回給客戶端。

至此,這個語句就執行完成了。

儲存引擎層

儲存引擎層負責資料的儲存和提取。我們可以為每張表指定不同的儲存引擎。其架構模式是外掛式的,支援 InnoDB、MyISAM、Memory 等多個儲存引擎。現在最常用的儲存引擎是 InnoDB,它從 MySQL 5.5.5 版本開始成為了預設儲存引擎。

InnoDB

InnoDB 大家都很熟悉,和其他儲存引擎的區別這裡不再展開。我們學習MySQL事務中常提到的 redo logundo log 就是 InnoDB 獨有的,這兩者都在儲存引擎層。

Binlog在Server層

MyISAM

這個只提兩點吧

  1. 不支援事務
  2. 只支援表級鎖

Memory

Memory引擎亦如其名,記憶體表。記憶體表把資料放在記憶體中,會帶來兩個顯著的影響:

  1. 讀寫速寫快
  2. 宕機或重啟資料會丟失

這裡不細說,僅僅提一下。

SQL執行流程

再次回到開始那張圖,我們就可以知道一條SQL是如何執行的了。

  1. 客戶端先通過聯結器建立連線,聯結器自會判斷使用者許可權
  2. (如果開啟了查詢快取並且匹配上key就直接返回結果給客戶端,不執行下面的流程)
  3. 分析器對SQL進行詞法分析與語法分析,明確SQL要做什麼
  4. 優化器生成執行計劃,選擇索引,明確怎麼做
  5. 執行器通過操作儲存引擎讀寫介面來獲取或更新資料,並將執行結果返回給客戶端

這篇文章說的很簡單,僅僅寫了一個SQL大概的執行流程,而對於索引的選擇,快取,log等都沒有提到。本篇只是要帶你認識下儲存引擎外的操作,在下一篇文章中,我會帶你仔細分析下一條SQL更新語句是如何執行的,InnoDB 內部是如何設計的。

下一篇 MySQL:一條更新語句是如何執行的