@
- 前言
- 背景
- 執行流程圖解
- 層級介紹
- Server 層
- 存儲引擎層
- 連接器
- 解析器
- 預處理器
- 優化器
- 執行計劃
- 總結
前言
請各大網友尊重本人原創知識分享,謹記本人博客:南國以南i、微信公眾號:白碼夢想家
提示:以下是本篇文章正文內容,下面案例可供參考
背景
Hello 朋友們,今天是元旦也是新的一年,祝大家元旦快樂!新年繼續奮發向上!
接下來為大家開啓,面試題相關係列☞《對線面試官》自信出擊,讓 offer 手到擒來!!!
執行流程圖解
層級介紹
Server 層
連接器、查詢緩存、解析器、預處理器、優化器、執行計劃、執行器 等,涵蓋 MySQL 的大多數核心服務功能,以及所有的內置函數(如日期、時間、數學和加密函數等),所有跨存儲引擎的功能都在這一層實現,比如存儲過程、觸發器、視圖等。而存儲引擎層負責數據的存儲和提取。
存儲引擎層
其架構模式是插件式的,支持 InnoDB、MyISAM、Memory 等多個存儲引擎。現在最常用的存儲引擎是 InnoDB,它從 MySQL 5.5.5 版本開始成為了默認存儲引擎。
連接器
客户端與MySQL之間建立連接(三次握手),建立連接後就可以輸入密碼了,斷開的話就要經過四次揮手
mysql -h$ip -P$port -u$user -p
查詢緩存:
MySQL 拿到一個查詢請求後,會先到查詢緩存看看,之前是不是執行過這條語句。之前執行過的語句及其結果可能會以 key-value 對的形式,被直接緩存在內存中。key 是查詢的語句,value 是查詢的結果。如果你的查詢能夠直接在這個緩存中找到 key,那麼這個 value 就會被直接返回給客户端。
如果語句不在查詢緩存中,就會繼續後面的執行階段。執行完成後,執行結果會被存入查詢緩存中。你可以看到,如果查詢命中緩存,MySQL 不需要執行後面的複雜操作,就可以直接返回結果,這個效率會很高。
MySQL 8.0 版本直接將查詢緩存的整塊功能刪掉了,也就是説 8.0 開始徹底沒有這個功能了。
解析器
如果沒有命中查詢緩存,就要開始真正執行語句了。首先,MySQL 需要知道你要做什麼,因此需要對 SQL 語句做解析。
-
分析器先會做 “詞法分析” 。你輸入的是由多個字符串和空格組成的一條 SQL 語句,MySQL需要識別出裏面的字符串分別是什麼,代表什麼。MySQL從你輸入的"select"這個關鍵字識別出來,這是一個查詢語句。它也要把字符串“T”識別成“表名 T”,把字符串“ID”識別成“列ID”。
-
再做 “語法分析” 。根據詞法分析的結果,語法分析器會根據語法規則,判斷你輸入的這個 SQL 語句是否滿足 MySQL語法。如果你的語句不對,就會收到 “You have an error in your SQL syntax” 的錯誤提醒,比如下面這個語句select 少打了開頭的字母“s”。
mysql> elect * from t where ID=1;
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”的內容。
預處理器
詞法分析和語法分析會生成一個語法樹,預處理器則根據MySQL規則進一步檢查語法樹(解析樹)是否合法,例如,這裏將檢查數據表和數據列是否存在,還會解析名字和別名,看是否有歧義等。下一步預處理還會驗證權限。
優化器
優化器是在表裏面有多個索引的時候,決定使用哪個索引;或者在一個語句有多表關聯(join)的時候,決定各個表的連接順序。比如你執行下面這樣的語句,這個語句是執行兩個表的 join:
mysql> 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。
這兩種執行方法的邏輯結果是一樣的,但是執行的效率會有不同,而優化器的作用就是決定選擇使用哪一個方案。
執行計劃
優化器確定 SQL 語句的執行順序,生成一個執行計劃。 這個執行計劃表明應該使用哪些索引進行查詢(全表檢索還是使用索引檢索),表之間的連接順序如何,最後會按照執行計劃中的步驟調用存儲引擎提供的方法來真正的執行查詢,並將查詢結果返回給用户。
執行器:
開始執行的時候,要先判斷一下你對這個表 T 有沒有執行查詢的權限,如果沒有,就會返回沒有權限的錯誤,如下所示 (在工程實現上,如果命中查詢緩存,會在查詢緩存返回結果的時候,做權限驗證。查詢也會在優化器之前調用 precheck 驗證權限)。
mysql> select * from T where ID=10;
ERROR 1142 (42000): SELECT command denied to user 'b'@'localhost' for table 'T'
如果有權限,就打開表繼續執行。打開表的時候,執行器就會根據表的引擎定義,去使用這個引擎提供的接口。
比如我們這個例子中的表 T 中,ID 字段沒有索引,那麼執行器的執行流程是這樣的:
- 調用 InnoDB 引擎接口取這個表的第一行,判斷 ID 值是不是 10,如果不是則跳過,如果是則將這行存在結果集中;
- 調用引擎接口取“下一行”,重複相同的判斷邏輯,直到取到這個表的最後一行。
- 執行器將上述遍歷過程中所有滿足條件的行組成的記錄集作為結果集返回給客户端。
總結
我是南國以南i記錄點滴每天成長一點點,學習是永無止境的!轉載請附原文鏈接!!!
參考鏈接、參考鏈接、參考鏈接、