mysql_一條查詢語句的執行流程 原

mysql的邏輯架構

一條查詢語句的執行流程

select * from T where ID=10;

連接器

在完成經典的 TCP 握手後,連接器就要開始認證你的身份,這個時候用的就是你輸入的用戶名和密碼。如果用戶名密碼認證通過,連接器會到權限表裏面查出你擁有的權限。之後,這個連接裏面的權限判斷邏輯,都將依賴於此時讀到的權限。(這就意味着,一個用戶成功建立連接後,即使你用管理員賬號對這個用戶的權限做了修改,也不會影響已經存在連接的權限。修改完成後,只有再新建的連接纔會使用新的權限設置。)

查詢緩存

MySQL 拿到一個查詢請求後,會先到查詢緩存看看,之前是不是執行過這條語句。之前執行過的語句及其結果可能會以 key-value 對的形式,被直接緩存在內存中。key 是查詢的語句,value 是查詢的結果。如果你的查詢能夠直接在這個緩存中找到 key,那麼這個 value 就會被直接返回給客戶端。

但是大多數情況下建議不要使用查詢緩存,爲什麼呢?因爲查詢緩存往往弊大於利。

查詢緩存的失效非常頻繁,只要有對一個表的更新,這個表上所有的查詢緩存都會被清空。對於更新壓力大的數據庫來說,查詢緩存的命中率會非常低。除非你的業務就是有一張靜態表,很長時間纔會更新一次。比如,一個系統配置表,那這張表上的查詢才適合使用查詢緩存。

mysql可以通過query_cache_type參數配置默認不進行緩存。如果配置了不進行緩存,執行sql語句時,可以顯示指定使用緩存:
select SQL_CACHE * from T where ID=10;
需要注意的是,MySQL 8.0 版本直接將查詢緩存的整塊功能刪掉了,也就是說 8.0 開始徹底沒有這個功能了。

分析器

如果沒有命中查詢緩存,就要開始真正執行語句了.

分析器首先會進行sql解析。分爲以下幾個步驟:

1.詞法分析 
解析sql語句,比如從select關鍵字識別這是一個查詢語句,將"T"識別成"表名T",把"ID"識別成"列ID"
2.語法分析
根據語法規則,判斷你的sql是否滿足mysql語法

優化器

優化器是在表裏面有多個索引的時候,覺得使用哪個索引;或者有多表join的時候,決定各個表的連接順序。

select * from t1 join t2 using(ID)  where t1.c=10 and t2.d=20;

既可以先從表 t1 裏面取出 c=10 的記錄的 ID 值,再根據 ID 值關聯到表 t2,再判斷 t2 裏面 d 的值是否等於 20。

也可以先從表 t2 裏面取出 d=20 的記錄的 ID 值,再根據 ID 值關聯到 t1,再判斷 t1 裏面 c 的值是否等於 10。

這兩種執行方法的邏輯結果是一樣的,但是執行的效率會有不同,而優化器的作用就是決定選擇使用哪一個方案。

執行器

MySQL 通過分析器知道了你要做什麼,通過優化器知道了該怎麼做,於是就進入了執行器階段,開始執行語句。

select * from T where ID=10;

開始執行的時候,要先判斷一下你對這個表 T 有沒有執行查詢的權限。 如果有權限,就打開表繼續執行。打開表的時候,執行器就會根據表的引擎定義,去使用這個引擎提供的接口。 如果ID字段沒用索引,那麼執行流程是這樣的:

1. 調用 InnoDB 引擎接口取這個表的第一行,判斷 ID 值是不是 10,如果不是則跳過,如果是則將這行存在結果集中;
2. 調用引擎接口取“下一行”,重複相同的判斷邏輯,直到取到這個表的最後一行。
3. 執行器將上述遍歷過程中所有滿足條件的行組成的記錄集作爲結果集返回給客戶端。

參考

極客時間:《mysql實戰45講》

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