1. 程式人生 > 實用技巧 >基礎架構:一條SQL查詢語句是如何執行的?

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

導讀

  • 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內部執行的過程涉及到的內部模組有:聯結器、查詢快取、分析器、優化器、執行器、儲存引擎。

對PHP後端技術,對PHP架構技術感興趣的朋友,我的官方群點選此處,一起學習,相互討論。

PHP進階學習思維導圖、面試;文件、視訊資源免費獲取​kdocs.cn

群內已經有管理將知識體系整理好(原始碼,學習視訊等資料),歡迎加群免費領取。