一條查詢語句到底是如何執行的?
- 2020 年 4 月 3 日
- 筆記
文章目錄
- 1. 導讀
- 2. 擼它
- 2.1. 1. 連接器
- 2.2. 2. 查詢快取【廢材,8.0 版本完全刪除】
- 2.3. 3. 分析器
- 2.4. 4. 優化器
- 2.5. 5. 執行器
- 3. 總結
導讀
- Mysql在中小型企業中是個香餑餑,目前主流的資料庫之一,幾乎沒有一個後端開發者不會使用的,但是作為一個老司機,僅僅會用真的不夠。
- 今天陳某透過一個簡單的查詢語句來講述在Mysql內部的執行過程。 select * from table where id=10;
擼它
- 首先通過一張圖片來了解一下Mysql的基礎架構,如下:

- 從上圖可以看出,Mysql大致分為Server層和存儲引擎層兩部分。
- Server層包括連接器、查詢快取、分析器、優化器等,其中包含了Mysql的大多數核心功能以及所有的內置函數(如日期,時間函數等),所有跨存儲引擎的功能都在這一層實現,比如存儲過程、觸發器、視圖等。
- 存儲引擎層負責數據的存儲和提取。它的架構是可插拔式的,支援InnoDB、MyISAM等多個存儲引擎。Mysql中主流的存儲引擎是InnoDB,由於它對事務的支援讓它從Mysql5.5.5版本開始成為了默認的存儲引擎。
- 大致了解了整體架構,現在說說每一個基礎的模組都承擔著怎樣的責任。
1. 連接器
- 顧名思義,是客戶端和Mysql之間連接的媒介,負責登錄、獲取許可權、維持連接和管理連接。連接命令一般如下: mysql [-h] ip [- P] port -u [user] -p
- 在完成經典的TCP握手後,連接器會開始認證身份,要求輸入密碼。
- 密碼認證通過,連接器會查詢出擁有的許可權,即使管理員修改了許可權,也不會影響你這次的連接,只有重新連接才會生效。
- 密碼認證失敗,會收到提示資訊Access denied for user。
- 連接完成後,沒有後續動作的連接將會變成空閑連接,你可以輸入
show processlist
命令看到它。如下圖,其中的Command這一列顯示為sleep的這一行表示在系統裡面有一個空閑連接。

- 客戶端如果太長時間沒有執行動作,連接器將會自動斷開,這個時間由參數
wait_timeout
控制,默認值是8小時。 - 如果在連接被斷開之後,客戶端再次發送請求的話,就會收到一個錯誤提醒: Lost connection to MySQL server during query。這時候如果你要繼續,就需要重連,然後再執行請求了。
2. 查詢快取【廢材,8.0 版本完全刪除】
- 連接建立完成後,你就可以select語句了,執行之前會查詢快取。
- 查詢快取在Mysql中的是默認關閉的,因為快取命中率非常低,只要有對錶執行一個更新操作,這個表的所有查詢快取都將被清空。怎麼樣?一句廢材足以形容了!!!
- 廢材的東西不必多講,主流的Redis的快取你不用,別再搞這廢材了。
3. 分析器
- 如果沒有命中查詢快取,就要執行查詢了,但是在執行查詢之前,需要對SQL語句做解析,判斷你這條語句有沒有語法錯誤。
- 分析器會做 『詞法分析』 ,你輸入的無非可就是多個字元串和空格組成的SQL語句,MYSQL需要識別出裡面的字元串是什麼,代表什麼,有沒有關鍵詞等。
- MYSQL會從你輸入的select 這個關鍵字識別出來是一個查詢語句,table是表名,id是列名。
- 做完這些會做 『語法分析』 ,根據MYSQL定義的規則來判斷你的SQL語句有沒有語法錯誤,如果你的語法不對,就會收到類似如下的提醒: 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 'elect * from t where ID=1' at line 1
- 一般語法錯誤會提示第一個出現錯誤的位置,所以你要關注的是緊接「use near」的內容。
4. 優化器
- 經過分析器詞法和語法的分析,此時就能知道這條SQL語句是幹什麼的。但是在開始執行之前,MYSQL底層還要使用優化器對這條SQL語句進行優化處理。
- MYSQL內部會對這條SQL進行評估,比如涉及到多個索引會比較使用哪個索引代價更小、多表join的時候會考慮決定各個表的連接順序。
- 優化器的作用一句話總結:根據MYSQL內部的演算法決定如何執行這條SQL語句來達到MYSQL認為代價最小目的。
- 優化器階段完成後,這個語句的執行方案就確定了,接下來就交給執行器執行了。
5. 執行器
- MYSQL通過分析器知道了要做什麼,通過優化器知道了如何做,於是就進入了執行器階段。
- 執行器開始執行之前,需要檢查一下用戶對錶table有沒有執行的許可權,沒有返回許可權不足的錯誤,有的話就執行。
- 執行也是分類的,如果Id不是索引則全表掃描,一行一行的查找,如果是索引則在索引組織表中查詢,索引的查詢很複雜,其中涉及到B+樹等演算法,這裡不再詳細介紹。
總結
- 一條SQL語句在MYSQL內部執行的過程涉及到的內部模組有:連接器、查詢快取、分析器、優化器、執行器、存儲引擎。
- 至此,MYSQL的基礎架構已經講完了。