這道題應(yīng)該從 MySQL 架構(gòu)來理解镊尺,我們可以把 MySQL 拆解成幾個零件饵撑,如下圖所示
大致上來說,MySQL 可以分為?Server層和?存儲引擎層乃沙。
Server 層包括連接器诽表、查詢緩存唉锌、分析器、優(yōu)化器竿奏、執(zhí)行器袄简,包括大多數(shù) MySQL 中的核心功能,所有跨存儲引擎的功能也在這一層實(shí)現(xiàn)泛啸,包括?存儲過程绿语、觸發(fā)器、視圖等候址。
存儲引擎層包括 MySQL 常見的存儲引擎吕粹,包括?MyISAM、InnoDB 和 Memory?等岗仑,最常用的是 InnoDB匹耕,也是現(xiàn)在 MySQL 的默認(rèn)存儲引擎。存儲引擎也可以在創(chuàng)建表的時(shí)候手動指定荠雕,比如下面
CREATE TABLE t (i INT) ENGINE = <Storage Engine>;
然后我們就可以探討 MySQL 的執(zhí)行過程了
連接器
首先需要在 MySQL 客戶端登陸才能使用稳其,所以需要一個連接器來連接用戶和 MySQL 數(shù)據(jù)庫,我們一般是使用
mysql -u 用戶名 -p 密碼
來進(jìn)行 MySQL 登陸炸卑,和服務(wù)端建立連接既鞠。在完成?TCP 握手?后,連接器會根據(jù)你輸入的用戶名和密碼驗(yàn)證你的登錄身份盖文。如果用戶名或者密碼錯誤嘱蛋,MySQL 就會提示?Access denied for user,來結(jié)束執(zhí)行五续。如果登錄成功后洒敏,MySQL 會根據(jù)權(quán)限表中的記錄來判定你的權(quán)限。
查詢緩存
連接完成后返帕,你就可以執(zhí)行 SQL 語句了桐玻,這行邏輯就會來到第二步:查詢緩存。
MySQL 在得到一個執(zhí)行請求后荆萤,會首先去?查詢緩存?中查找镊靴,是否執(zhí)行過這條 SQL 語句,之前執(zhí)行過的語句以及結(jié)果會以?key-value?對的形式链韭,被直接放在內(nèi)存中偏竟。key 是查詢語句,value 是查詢的結(jié)果敞峭。如果通過 key 能夠查找到這條 SQL 語句踊谋,就直接返回 SQL 的執(zhí)行結(jié)果。
如果語句不在查詢緩存中旋讹,就會繼續(xù)后面的執(zhí)行階段殖蚕。執(zhí)行完成后轿衔,執(zhí)行結(jié)果就會被放入查詢緩存中∧酪撸可以看到害驹,如果查詢命中緩存,MySQL 不需要執(zhí)行后面的復(fù)雜操作蛤育,就可以直接返回結(jié)果宛官,效率會很高。
但是查詢緩存不建議使用
為什么呢瓦糕?因?yàn)橹灰?MySQL 中對某一張表執(zhí)行了更新操作底洗,那么所有的查詢緩存就會失效,對于更新頻繁的數(shù)據(jù)庫來說咕娄,查詢緩存的命中率很低亥揖。
分析器
如果沒有命中查詢,就開始執(zhí)行真正的 SQL 語句谭胚。
首先徐块,MySQL 會根據(jù)你寫的 SQL 語句進(jìn)行解析,分析器會先做?詞法分析灾而,你寫的 SQL 就是由多個字符串和空格組成的一條 SQL 語句胡控,MySQL 需要識別出里面的字符串是什么,代表什么旁趟。
然后進(jìn)行?語法分析昼激,根據(jù)詞法分析的結(jié)果, 語法分析器會根據(jù)語法規(guī)則锡搜,判斷你輸入的這個 SQL 語句是否滿足 MySQL 語法橙困。如果 SQL 語句不正確,就會提示?You have an error in your SQL syntax
優(yōu)化器
經(jīng)過分析器的詞法分析和語法分析后耕餐,你這條 SQL 就合法了凡傅,MySQL 就知道你要做什么了。但是在執(zhí)行前肠缔,還需要進(jìn)行優(yōu)化器的處理夏跷,優(yōu)化器會判斷你使用了哪種索引,使用了何種連接明未,優(yōu)化器的作用就是確定效率最高的執(zhí)行方案槽华。
執(zhí)行器
MySQL 通過分析器知道了你的 SQL 語句是否合法,你想要做什么操作趟妥,通過優(yōu)化器知道了該怎么做效率最高猫态,然后就進(jìn)入了執(zhí)行階段,開始執(zhí)行這條 SQL 語句
在執(zhí)行階段,MySQL 首先會判斷你有沒有執(zhí)行這條語句的權(quán)限亲雪,沒有權(quán)限的話勇凭,就會返回沒有權(quán)限的錯誤。如果有權(quán)限匆光,就打開表繼續(xù)執(zhí)行套像。打開表的時(shí)候酿联,執(zhí)行器就會根據(jù)表的引擎定義终息,去使用這個引擎提供的接口。對于有索引的表贞让,執(zhí)行的邏輯也差不多周崭。
至此,MySQL 對于一條語句的執(zhí)行過程也就完成了喳张。