MySQL 中一條 SQL 語句是如何執(zhí)行的?
MySQL執(zhí)行一條SQL語句,涉及到以下幾個過程:
客戶端連接
要執(zhí)行 SQL 語句,首先用戶需要通過客戶端連接到MySQL服務(wù)器,連接時需要指定用戶名和密碼,MySQL服務(wù)器中的連接器模塊會對用戶提供的用戶名和密碼進行驗證,并檢查用戶是否擁有執(zhí)行特定SQL語句的權(quán)限。一個用戶成功建立連接后,即使管理員對這個用戶的權(quán)限做了修改,也不會影響已經(jīng)存在連接的權(quán)限。修改完成后,只有新建的連接才會使用新的權(quán)限設(shè)置。
查詢緩存
如果執(zhí)行的是一條查詢語句,MySQL會先到查詢緩存中查找之前是不是執(zhí)行過這條語句,如果能在緩存中找到,就直接返回查詢結(jié)果。如果找不到,就繼續(xù)往下執(zhí)行。需要注意的是,如果一個表經(jīng)常更新,查詢緩存就會被頻繁清空,導(dǎo)致緩存的命中率非常低,所以MySQL 8.0 版本后,查詢緩存的功能被刪掉了。
解析SQL
在執(zhí)行某條SQL語句之前,MySQL需要先弄懂它的含義,所以需要解析器對 SQL 語句做解析。解析器首先會對SQL語句進行詞法分析,也就是將SQL語句字符串中的關(guān)鍵字識別出來,比如select,from等等。接著解析器再根據(jù)詞法分析的結(jié)果,對SQL語句進行語法分析構(gòu)建出 SQL 語法樹,方便后面模塊獲取 SQL 類型、表名、字段名、 where 條件等等。
執(zhí)行SQL
在正式執(zhí)行SQL之前,還會經(jīng)過預(yù)處理和優(yōu)化兩個階段。預(yù)處理階段,預(yù)處理器會檢查 SQL 語句中的表或者字段是否存在。優(yōu)化階段,優(yōu)化器負責將SQL語句的執(zhí)行方案確定下來,比如在表里面有多個索引的時候,優(yōu)化器會基于查詢成本的考慮,來決定選擇使用哪個索引。
經(jīng)過優(yōu)化器確定執(zhí)行方案后,就由執(zhí)行器真正開始執(zhí)行SQL語句,執(zhí)行器通過API與存儲引擎交互,獲取數(shù)據(jù)或?qū)?shù)據(jù)進行修改,并將執(zhí)行結(jié)果返回給用戶。
總的來說,MySQL執(zhí)行一條SQL語句,會經(jīng)過連接器處理客戶端連接、查詢緩存、解析器進行詞法分析和語法分析生成語法樹、預(yù)處理器檢查表名和字段名、優(yōu)化器確定最優(yōu)執(zhí)行計劃以及最后執(zhí)行器與存儲引擎交互進行數(shù)據(jù)操作等多個流程。