MySQL 可以分為 Server 層和存儲(chǔ)引擎層兩部分缠诅。
Server 層包括連接器乍迄、查詢緩存、分析器闯两、優(yōu)化器、執(zhí)行器等重慢,涵蓋 MySQL 的大多數(shù)核心服務(wù)功能逊躁,以及所有的內(nèi)置函數(shù)(如日期、時(shí)間核芽、數(shù)學(xué)和加密函數(shù)等),所有跨存儲(chǔ)引擎的功能都在這一層實(shí)現(xiàn)轧简,比如存儲(chǔ)過(guò)程匾二、觸發(fā)器拳芙、視圖等。
而存儲(chǔ)引擎層負(fù)責(zé)數(shù)據(jù)的存儲(chǔ)和提取舟扎。其架構(gòu)模式是插件式的恶导,支持 InnoDB、MyISAM惨寿、Memory 等多個(gè)存儲(chǔ)引擎。現(xiàn)在最常用的存儲(chǔ)引擎是 InnoDB裂垦,它從 MySQL 5.5.5 版本開(kāi)始成為了默認(rèn)存儲(chǔ)引擎顺囊。
連接器
第一步蕉拢,你會(huì)先連接到這個(gè)數(shù)據(jù)庫(kù)上,這時(shí)候接待你的就是連接器晕换。連接器負(fù)責(zé)跟客戶端建立連接午乓、獲取權(quán)限闸准、維持和管理連接。連接命令一般是這么寫(xiě)的:
mysql -h$ip -P$port -u$user -p
數(shù)據(jù)庫(kù)里面蒸其,長(zhǎng)連接是指連接成功后库快,如果客戶端持續(xù)有請(qǐng)求摸袁,則一直使用同一個(gè)連接义屏。短連接則是指每次執(zhí)行完很少的幾次查詢就斷開(kāi)連接,下次查詢?cè)僦匦陆⒁粋€(gè)膀曾。
建立連接的過(guò)程通常是比較復(fù)雜的阳啥,所以我建議你在使用中要盡量減少建立連接的動(dòng)作,也就是盡量使用長(zhǎng)連接察迟。
但是全部使用長(zhǎng)連接后,你可能會(huì)發(fā)現(xiàn)扎瓶,有些時(shí)候 MySQL 占用內(nèi)存漲得特別快,這是因?yàn)?MySQL 在執(zhí)行過(guò)程中臨時(shí)使用的內(nèi)存是管理在連接對(duì)象里面的秕岛。這些資源會(huì)在連接斷開(kāi)的時(shí)候才釋放误证。所以如果長(zhǎng)連接累積下來(lái)继薛,可能導(dǎo)致內(nèi)存占用太大愈捅,被系統(tǒng)強(qiáng)行殺掉(OOM),從現(xiàn)象看就是 MySQL 異常重啟了灌具。
怎么解決這個(gè)問(wèn)題呢譬巫?你可以考慮以下兩種方案咖楣。
定期斷開(kāi)長(zhǎng)連接芦昔。使用一段時(shí)間,或者程序里面判斷執(zhí)行過(guò)一個(gè)占用內(nèi)存的大查詢后瘪松,斷開(kāi)連接,之后要查詢?cè)僦剡B宵睦。
如果你用的是 MySQL 5.7 或更新版本墅诡,可以在每次執(zhí)行一個(gè)比較大的操作后,通過(guò)執(zhí)行 mysql_reset_connection 來(lái)重新初始化連接資源末早。這個(gè)過(guò)程不需要重連和重新做權(quán)限驗(yàn)證,但是會(huì)將連接恢復(fù)到剛剛創(chuàng)建完時(shí)的狀態(tài)郑趁。
查詢緩存
連接建立完成后,你就可以執(zhí)行 select 語(yǔ)句了寡润。執(zhí)行邏輯就會(huì)來(lái)到第二步:查詢緩存。
MySQL 拿到一個(gè)查詢請(qǐng)求后梭纹,會(huì)先到查詢緩存看看,之前是不是執(zhí)行過(guò)這條語(yǔ)句础拨。之前執(zhí)行過(guò)的語(yǔ)句及其結(jié)果可能會(huì)以 key-value 對(duì)的形式,被直接緩存在內(nèi)存中诡宗。
但是大多數(shù)情況下我會(huì)建議你不要使用查詢緩存逛钻,為什么呢?因?yàn)椴樵兙彺嫱状笥诶?/p>
查詢緩存的失效非常頻繁曙痘,只要有對(duì)一個(gè)表的更新,這個(gè)表上所有的查詢緩存都會(huì)被清空名扛。因此很可能你費(fèi)勁地把結(jié)果存起來(lái),還沒(méi)使用呢肮韧,就被一個(gè)更新全清空了旺订。
分析器
如果沒(méi)有命中查詢緩存,就要開(kāi)始真正執(zhí)行語(yǔ)句了区拳。首先,MySQL 需要知道你要做什么樱调,因此需要對(duì) SQL 語(yǔ)句做解析。
分析器先會(huì)做“詞法分析”圣猎。你輸入的是由多個(gè)字符串和空格組成的一條 SQL 語(yǔ)句乞而,MySQL 需要識(shí)別出里面的字符串分別是什么,代表什么爪模。
做完了這些識(shí)別以后鳍怨,就要做“語(yǔ)法分析”跪妥。根據(jù)詞法分析的結(jié)果声滥,語(yǔ)法分析器會(huì)根據(jù)語(yǔ)法規(guī)則,判斷你輸入的這個(gè) SQL 語(yǔ)句是否滿足 MySQL 語(yǔ)法落塑。
優(yōu)化器
經(jīng)過(guò)了分析器,MySQL 就知道你要做什么了憾赁。在開(kāi)始執(zhí)行之前,還要先經(jīng)過(guò)優(yōu)化器的處理蟆肆。
優(yōu)化器是在表里面有多個(gè)索引的時(shí)候晦款,決定使用哪個(gè)索引;或者在一個(gè)語(yǔ)句有多表關(guān)聯(lián)(join)的時(shí)候缓溅,決定各個(gè)表的連接順序。
執(zhí)行器
MySQL 通過(guò)分析器知道了你要做什么淤齐,通過(guò)優(yōu)化器知道了該怎么做,于是就進(jìn)入了執(zhí)行器階段更啄,開(kāi)始執(zhí)行語(yǔ)句沉帮。
開(kāi)始執(zhí)行的時(shí)候,要先判斷一下你對(duì)這個(gè)表 T 有沒(méi)有執(zhí)行查詢的權(quán)限穆壕,如果沒(méi)有,就會(huì)返回沒(méi)有權(quán)限的錯(cuò)誤缨该。
如果有權(quán)限,就打開(kāi)表繼續(xù)執(zhí)行贰拿。打開(kāi)表的時(shí)候,執(zhí)行器就會(huì)根據(jù)表的引擎定義膨更,去使用這個(gè)引擎提供的接口。
此文章為11月Day9學(xué)習(xí)筆記珍德,內(nèi)容來(lái)源于極客時(shí)間《MySQL實(shí)戰(zhàn)45講》矗漾,強(qiáng)烈推薦該課程