基礎架構:一條SQL查詢語句是如何執行的?

學習筆記:

MySQL基本架構圖

其實一條SQL的查詢語句的執行並不是很複雜!

我們就從最簡單的一條查詢語句來入手分析這個問題。
比如一條SELECT * FROM T WHERE ID=10;這樣的語句它的整個執行的流程是怎麼樣的呢?

上圖就是MySQL的結構圖,從結構上我們能看到MySQL的結構主要分爲兩層:

  • server層
    主要包括:連接器、查詢緩存、分析器、優化器、執行器等
  • 引擎層
    引擎層主要是負責數據的存儲和讀取

連接器

連接器主要是負責連接MySQL客戶端並獲取權限以及維持連接狀態。我們想要執行MySQL語句之前先要連接MySQL客戶端,執行語句:

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

執行上面語句的時候會出現以下兩種情況:

  • 如果用戶名或者密碼不正確則會出現報錯ERROR 1045 (28000): Access denied for user 'test'@'localhost' (using password: NO),相信這個報錯大多數用過MySQL的人都遇到過,從字面上也很好理解,訪問拒絕對於test這個用戶,然後程序結束。
  • 如果用戶名和密碼正確則會進入MySQL客戶端界面。在進入之前,MySQL會根據用戶名查詢出該用戶擁有的權限,這個連接中的所有權限校驗都是依賴於之前查詢的權限。

查詢緩存

NOTE
The query cache is deprecated as of MySQL 5.7.20, and is removed in MySQL 8.0

查詢緩存是指輸入查詢語句,MySQL會優先執行查詢緩存,如果命中緩存則直接返回查詢結果。在MySQL中對於每次查詢的結果會有緩存,每次有對於數據庫表結構或者數據的修改,緩存就會失效。如果沒有命中緩存就會繼續往下執行。
所以在大多數情況下緩存的命中率是很低的,除非是一張更新頻率非常低的靜態表,否則緩存的命中率會非常的低。MySQL官方也是在MySQL8.0中放棄了對於查詢緩存的支持。所以在大多數情況下是不建議使用查詢緩存的。
關於查詢緩存的配置請參考官方文檔操作:Query Cache Configuration

分析器

沒有命中緩存,就要開始執行真正的執行語句了。分析器的工作主要是對輸入的SQL語句做解析。
首先會做"詞法分析",當你輸入一竄SQL語句的時候,系統要先能識別T是一個表名,ID是字段名,WHERE和SELECT是一個MySQL的關鍵字…等。
做完了這些之後就會進行"語法分析",語法分析就是判斷這些關鍵字是否合法,如果你輸入的SQL語句語法不正確就是有提示,比如WHERE關鍵字少個W

SELECT * FROM T HERE ID = 10;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ID = 10' at line 1

通過以上的輸出,我們能看到語法的檢測是在分析器階段執行的,如果遇到syntax error,只需要關注use near關鍵字後面的部分。

優化器

優化器顧名思義就是對SQL語句做優化的步驟,那就有同學有問題了,SQL語句都寫好了,MySQL系統還能對其做優化?答案是:當然能。

SELECT * FROM t1 JOIN t2 ON `id` WHERE t1.a = 10 AND t2.b = 20;

上面是一條簡單的SQL語句,系統的執行順序可以如下:

  • 可以先查詢t1表中a字段等於10的數據,然後根據查詢結果通過ID關聯t2表,判斷t2表中的b字段是否等於20。
  • 也可以先查詢t2表中b字段等於20的數據,然後根據插敘結果通過ID關聯到t1表,判斷t1表a字段是否等於10。

還有一些是關於數據庫索引的優化,這個部分比較複雜,後面會單獨講到。

執行器

當前面幾個步驟完成的時候就開始進入到執行器階段,執行器首先會做權限校驗,判斷當前用戶是否有該SQL語句的操作權限,如果沒有則會報錯。

DELETE FROM t;
ERROR 1142 (42000): DELETE command denied to user 'test'@'localhost' for table 't'

如果權限校驗也通過就會真正的執行查詢,查詢是通過調用引擎提供的API。

引擎

引擎層是通過插件的形式存在的,存儲引擎負責MySQL中數據的儲存和提取。服務器通過API與儲存引擎行進通信,這些API屏蔽了不同引擎之間的差異,使得引擎的差異對服務層沒有影響。不同的數據存儲引擎之間也是不通信的,互相之間不會影響。

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