一條查詢語句到底是如何執行的?

文章目錄

  1. 1. 導讀
  2. 2. 擼它
    1. 2.1. 1. 連接器
    2. 2.2. 2. 查詢快取【廢材,8.0 版本完全刪除】
    3. 2.3. 3. 分析器
    4. 2.4. 4. 優化器
    5. 2.5. 5. 執行器
  3. 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的基礎架構已經講完了。