九、MySQL基礎架構概述

MySQL基礎架構

SELECT * FROM student WHERE stu_id = 007;

這樣一條簡單的 SQL 語句,可以從 student 表中查詢得到 stu_id 爲 007 的數據,學會寫 SQL 語句後,在使用數據庫時,只能觀察到數據庫執行了 SQL 語句,並且返回了所需要的數據。那麼,MySQL 在拿到 SQL 語句之後做了哪些操作呢?

這涉及到 MySQL 的基礎架構設計,分爲 Service 層和存儲引擎層,Service 層負責處理與客戶端通信、SQL語句的解析和所有內置函數等,而存儲引擎層則提供數據的存儲和讀寫接口,其中 Service 層又包含了連接器緩存優化器分析器執行器。存儲引擎層,包含了不同的存儲引擎,MySQL 默認是 InnoDB,此外還有 MyISAM 引擎。詳見下圖:

在這裏插入圖片描述

  1. 連接器:負責接待客戶端,驗證權限
  2. 緩存:查詢時,若命中緩存則直接返回結果
  3. 分析器:分析 SQl 語句的語法和詞法
  4. 優化器:確定 SQL 語句的最佳執行方案
  5. 執行器:根據優化器的方案,操作存儲引擎拿到結果並返回

連接器

連接器的工作,就是負責處理所有客戶端的連接請求,在完成TCP握手後,驗證賬號密碼,並且得到對應的權限信息,用於這個連接後續對數據庫操作時的權限判斷。

可以通過show processlist查看當前的連接數:

mysql> show processlist;
+----+------+-----------------+-------+---------+-------+----------+------------------+
| Id | User | Host            | db    | Command | Time  | State    | Info             |
+----+------+-----------------+-------+---------+-------+----------+------------------+
|  2 | root | localhost:3044  | NULL  | Sleep   | 16858 |          | NULL             |
|  3 | root | localhost:3052  | uccdb | Sleep   | 16788 |          | NULL             |
|  4 | root | localhost:39029 | NULL  | Query   |     0 | starting | show processlist |
+----+------+-----------------+-------+---------+-------+----------+------------------+
3 rows in set

Command 爲Sleep的是空閒連接。

值得注意的是

  1. 空閒連接在特定時間後會失去連接,這個時間參數是wait_timeout
--臨時修改wait_timeout,重啓後失效
set  global wait_timeout=28800;--8小時

--也可以通過修改 my.ini 配置文件
  1. 每一個連接執行操作後,使用的內存是在連接對象中的,直到連接斷開纔會釋放,而重新連接的成本也不低,因此可以在執行大操作後,使用mysql_reset_connection(是API不是可執行的SQL)來重置資源。

緩存

在執行查詢語句後,查詢語句以及對應的結果集會被記錄到緩存中,下次遇到同樣的查詢時,直接從緩存中返回即可。

緩存雖然看似可以提高查詢效率,但是在實際應用中卻沒有什麼作用,甚至反而降低了效率。因爲只要某個表更新了數據,那麼這個表相關的緩存就會被清除,如果是更新比較頻繁的業務,那麼緩存幾乎沒有任何作用,反而爲了維護緩存做了更多的無用功。

通常建議關閉緩存,MySQL 8.0 中也已經移除了緩存這個機制。

分析器

分析器有兩個作用,一個是詞法分析,一個是語法分析。

MySQL要知道你給的 SQL 語句是什麼意思,在分析器之前,SQL 語句只是一個字符串而已,分析器要做的首先就是詞法分析,解析 SQL 語句,分析每個單詞的含義,例如開頭select的,是查詢語句。

分析完單詞的含義之後,接着是語法分析,也就是檢查這句 SQL 語句有沒有語法錯誤。

全部通過後,就將解析後的SQl語句交給優化器。

這裏需要注意的是,分析器除了分析詞法和語法,還會判斷表、字段等是否存在。

優化器

優化器的作用就是要把這句 SQL 語句的執行方案定下來,當然,肯定是優化器認爲的效率最高的那個方案(有的時候優化器並不靠譜)。

經過分析器分析後,MySQL 已經知道你想要做什麼了,此時交給分析器來決定使用哪個索引,如果有多個表的連接查詢,那麼確定先連哪個表。

最後確定了執行計劃後,交給執行器去實施這個計劃。

執行器

執行器階段首先要做的就是判斷送來這個SQL語句的客戶端有沒有權限去執行。

確認有權限執行後,執行器會打開相應的表,根據引擎定義的接口去取數據。這裏以開頭的SQL語句爲例(無索引):

SELECT * FROM student WHERE stu_id = 007;

執行步驟爲:

  1. 打開表student
  2. 調用引擎的讀數據接口按順序取一行數據
  3. 判斷stu_id是否爲007,重複步驟2
  4. 直到掃描完全表,返回所有符合的數據

至於存在索引的情況,是根據索引的規則來取數據,例如,索引是按stu_id排序的,那麼可以二分查找快速找到對應數據,即合適的索引可以提高查詢效率。

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