天天都在跟 mysql 打交道,你知道執行一條簡單的 select 語句,都經歷了哪些過程嗎?mysql
首先,mysql 主要是由 server 層和存儲層兩部分構成的。server 層主要包括鏈接器、查詢緩存,分析器、優化器、執行器。存儲層主要是用來存儲和查詢數據的,經常使用的存儲引擎有 InnoDB、MyISAM,MySQL 5.5.5版本後使用 InnoDB 做爲默認存儲引擎。sql
鏈接器緩存
鏈接器主要負責將 mysql 客戶端和服務端創建鏈接,鏈接成功後,會獲取當前鏈接用戶的權限。這裏獲取到的權限對整個鏈接都有效,一旦鏈接成功後,若是使用管理員帳號對該用戶更改權限,當前鏈接中的擁有的權限保持不變,只有等到下次從新鏈接纔會更新權限。優化
查詢緩存server
鏈接成功後,即開始要正式執行 select 語句了,可是在執行查詢以前,mysql 會去看下有沒有該條語句的緩存內容,若是有緩存直接從緩存中讀取並返回數據,再也不執行後面的步驟了,結束查詢操做。索引
若是沒有緩存則繼續日後執行,並將執行結果和語句保存在緩存中。接口
注意在 mysql8 後已經沒有查詢緩存這個功能了,由於這個緩存很是容易被清空掉,命中率比較低。只要對錶有一個更新,這個表上的全部緩存就會被清空,所以你剛緩存下來的內容,還沒來得及用就被另外一個更新給清空了。效率
分析器原理
既然沒有查到緩存,就須要開始執行 sql 語句了,在執行以前確定須要先對 sql 語句進行解析。分析器主要對 sql 語句進行語法和語義分析,檢查單詞是否拼寫錯誤,還有檢查要查詢的表或字段是否存在。select
若是分析器檢測出有錯誤就會返回相似 "You have an error in your sql" 這樣的錯誤信息,並結束查詢操做。
優化器
經過分析器以後,mysql 就算是理解了你要執行的操做了。一般對於同一個 sql 語句,mysql 內部可能存在多種執行方案,好比存在多個索引時,該選擇哪一個索引,多個表關聯查詢時,怎麼確認各個表的鏈接順序。
這些方案的執行結果都同樣,可是執行效率不同,因此 mysql 在執行以前須要嘗試找出一個最優的方案來,這就是優化器的主要工做。可是 mysql 也會有選擇錯誤方案的時候,這裏暫不細說,留到後面再解釋緣由。
執行器
通過優化器選定了一個方案後,執行器就按照選定的方案執行 sql 語句。前面咱們有講過,在鏈接器中會讀取當前用戶的權限,鏈接器中只是獲取權限而已,並無對權限進行判斷和校驗。
因此在執行器中,在執行語句以前會判斷權限,若是沒有對應的權限則會直接返回並提示沒有相關權限。
這裏你可能會問,爲何不在鏈接器中就直接判斷權限呢,這裏我以爲多是由於 mysql 要查詢的表並不必定僅限於 sql 語句中字面上的那些表,有的時候可能須要通過分析器和優化器以後才能肯定到底要怎麼執行,因此權限校驗放在執行器中是有道理的。
注意若是是在前面的查詢緩存中查到緩存以後,也會在返回結果前作權限校驗的。
權限校驗經過以後,就繼續打開表,調用存儲引擎提供的接口去查詢並返回結果集數據。
到這裏,一條查詢 sql 語句就執行結束了。講的比較粗糙,只是一個大體的流程,其中每一步在 mysql 的底層實現都很是複雜,後面再講一講索引的底層實現原理。