大體來說,MySQL 可以分為 Server 層和存儲引擎層兩部分。 select * from T where ID=10; 這條查詢語句的執行過程: 外部層: 用戶與server層交互的媒介 一.客戶端【用於連接資料庫,輸入命令/語句】 界面化連接資料庫 輸入 select * from T w ...
大體來說,MySQL 可以分為 Server 層和存儲引擎層兩部分。
select * from T where ID=10;
這條查詢語句的執行過程:
外部層:
用戶與server層交互的媒介
一.客戶端【用於連接資料庫,輸入命令/語句】
界面化連接資料庫
輸入 select * from T where ID=10;
server層:
Server 層包括連接器、查詢緩存、分析器、優化器、執行器等,涵蓋 MySQL 的大多數核心服務功能,以及所有的內置函數(如日期、時間、數學和加密函數等),所有跨存儲引擎的功能都在這一層實現,比如存儲過程、觸發器、視圖等。
二.連接器【連接器負責跟客戶端建立連接、獲取許可權、維持和管理連接。】
輸入連接命令認證身份--mysql -h$ip -P$port -u$user -p
認證通過:連接器會到許可權表裡查詢帳號許可權
P:之後所有的許可權判斷邏輯都會依賴此時讀到的許可權
這意味著,一個用戶成功建立連接後,即使你用管理員賬號對這個用戶的許可權做了修改,也不會影響已經存在連接的許可權。修改完成後,只有再新建的連接才會使用新的許可權設置。
認證失敗:Access denied for user
連接完成後可以使用命令:show processlist查看狀態
Command 列顯示為“Sleep”的這一行,就表示現在連接處於空閑狀態
客戶端如果太長時間沒動靜,連接器就會自動將它斷開。這個時間是由參數 wait_timeout 控制的,預設值是 8 小時。
連接方式分為兩種 :【長連接和短連接】
定義:
長連接是指連接成功後,如果客戶端持續有請求,則一直使用同一個連接。
短連接則是指每次執行完很少的幾次查詢就斷開連接,下次查詢再重新建立一個。
利弊:
建立連接過程複雜,儘量使用長連接,減少建立連接操作
全部使用長連接記憶體增長過快(PS:MySQL在執行時臨時使用的記憶體管理器在連接對象里,這些資源只有在連接斷開的時候釋放,長連接累積下來記憶體占用過大,會被系統殺掉,現象就是異常重啟)
弊端的優化方法:
定期斷開長連接。使用一段時間,或者程式裡面判斷執行過一個占用記憶體的大查詢後,斷開連接,之後要查詢再重連。
如果你用的是 MySQL 5.7 或更新版本,可以在每次執行一個比較大的操作後,通過執行 mysql_reset_connection 來重新初始化連接資源。這個過程不需要重連和重新做許可權驗證,但是會將連接恢復到剛剛創建完時的狀態。
三.查詢緩存
連接建立完成後,進入執行階段
當MySQL拿到一個查詢請求後,會先到查詢緩存內查看key值,如果命中直接回返回結果。
PS:之前執行過的語句及結果會以鍵值對的形式緩存到記憶體中,{key(查詢語句):value(查詢結果)}
弊端:
查詢緩存的失效--只要對錶更新,此表上的所有查詢緩存就會失效。。so一半隻有在很長時間不會更新的表才會使用查詢緩存,例如:系統配置表
如果不需要使用查詢緩存功能,將參數 query_cache_type 設置成 DEMAND,而對於需要使用的語句可以使用“SQL_CACHE”單獨指定出來:select SQL_CACHE * from T where ID=10;
四.分析器
現在是查詢語句並沒有在查詢緩存中找到相應的key值,因此它需要對語句進行解析。
①,詞法分析
輸入的語句是由多個字元串和空格組成的,MySQL 需要識別出裡面的字元串分別是什麼,代表什麼
例如:MySQL 從你輸入的"select"這個關鍵字識別出來,這是一個查詢語句。
②,語法分析
錯誤提示You have an error in your SQL syntax,要關註的是緊接“use near”
五.優化器
優化器的作用是確定執行方案
在經過分析器後,MySQL已經知道你要乾什麼,現在需要優化器來確定使用哪一個執行方案,例如:
select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;
這條語句是t1和t2兩個表的join,它會有多種執行方式,雖然結果相同但是效率會有很大的不同
六.執行器
MySQL通過分析器知道了要乾什麼,通過優化器知道了要怎麼做,現在到了執行器,進入執行語句階段
①,判斷許可權
判斷你是否有查詢許可權(此時的判斷依據為連接器時讀取到的許可權),如有許可權就可以打開表繼續執行。
②,判斷引擎
打開表的時候,執行器就會根據表的引擎定義,去使用這個引擎提供的介面。
③,執行語句
select * from T where ID=10;這條查詢語句的執行過程為--【表 T 中,ID 欄位沒有索引】
調用 InnoDB 引擎介面取這個表的第一行,判斷 ID 值是不是 10,如果不是則跳過,如果是則將這行存在結果集中;
調用引擎介面取“下一行”,重覆相同的判斷邏輯,直到取到這個表的最後一行。
執行器將上述遍歷過程中所有滿足條件的行組成的記錄集作為結果集返回給客戶端。
存儲層:
存儲引擎層負責數據的存儲和提取。其架構模式是插件式的,支持 InnoDB、MyISAM、Memory 等多個存儲引擎。現在最常用的存儲引擎是 InnoDB,它從 MySQL 5.5.5 版本開始成為了預設存儲引擎。
create table建表時不指定引擎使用的預設引擎,可以在語句中添加engine=memory指定引擎
附加:
如果表 T 中沒有欄位 k,而你執行了這個語句 select * from T where k=1, 那肯定是會報“不存在這個列”的錯誤: “Unknown column ‘k’ in ‘where clause’”。你覺得這個錯誤是在我們上面提到的哪個階段報出來的呢?
【個人理解】
分析器會對語法和詞法進行分析判斷,在此階段會判斷語句的正確性