深入理解MySQL底層架構(gòu),看這一篇文章就夠了!
前面我們已經(jīng)講解了,我們的系統(tǒng)是如何與MySQL打交道的?,我們開發(fā)的系統(tǒng)與MySQL本身,都維護(hù)的有線程池,管理了所有連接??聪聢D回顧下:

圖1 我們的系統(tǒng)是如何與MySQL打交道的?
從上圖我們可以看到,我們通過數(shù)據(jù)庫連接,把要執(zhí)行的SQL語句發(fā)送給MySQL數(shù)據(jù)庫進(jìn)行增刪改查就可以了。
然而MySQL數(shù)據(jù)庫內(nèi)部到底是怎么運(yùn)轉(zhuǎn)的呢?
1、網(wǎng)絡(luò)連接讓工作線程去具體執(zhí)行
一般,網(wǎng)絡(luò)服務(wù)器會(huì)分配一個(gè)線程或線程池去處理網(wǎng)絡(luò)連接,把網(wǎng)絡(luò)連接中讀取出來的數(shù)據(jù)交給另外的線程或線程池處理。如下圖所示:

圖2 多線程處理網(wǎng)絡(luò)請(qǐng)求數(shù)據(jù)
當(dāng)MySQL內(nèi)部的工作線程從一個(gè)網(wǎng)絡(luò)連接中讀取一個(gè)SQL語句后,此時(shí)會(huì)如何處理這個(gè)SQL呢?
2、SQL接口,處理接收到的SQL語句
此時(shí)工作線程會(huì)把接收到的SQL語句交給一個(gè)叫SQL接口的組件執(zhí)行。SQL接口(SQL interface),是一套執(zhí)行SQL語句的接口,專門用于執(zhí)行我們發(fā)送給MySQL的那些增刪改查的SQL語句。

圖3 SQL接口
3、查詢解析器:讓MySQL讀懂你的SQL
接下來SQL接口怎么處理SQL語句呢?MySQL必須理解你的SQL語法,才可以去執(zhí)行,要理解SQL語法,就要靠查詢解析器了。
查詢解析器(parser),就是負(fù)責(zé)對(duì)SQL語句進(jìn)行解析的。按照SQL語法,對(duì)我們按照SQL語法編寫的SQL語句進(jìn)行解析。比如對(duì)select name, age from user where id = 1這個(gè)語句。
1、我們要從user表里查詢數(shù)據(jù);
2、查詢"id"字段值等于1的那行語句;
3、對(duì)查出來的那行數(shù)據(jù)提取name,age兩個(gè)字段;

圖4 SQL查詢解析器
4、查詢優(yōu)化器:選擇最優(yōu)的查詢路徑
通過SQL解析器解析SQL語句,知道要干什么,那么怎么干性能最高呢?
比如,上面那個(gè)查詢語句:select name, age from user where id = 1
可以有多種查詢方式:
1、直接根據(jù)id定位到一行數(shù)據(jù),然后從中獲取name, age;
2、從表中把所有的id,name, age查出來,根據(jù)id過濾出來想要的數(shù)據(jù);
上面是兩種SQL查詢方式(不代表MySQL的實(shí)現(xiàn)方式),兩種查詢方式都可以實(shí)現(xiàn)目標(biāo),哪種性能更好呢?
這就需要查詢優(yōu)化器告訴你。
查詢優(yōu)化器會(huì)告訴你,你應(yīng)該按照一個(gè)什么樣的步驟和順序,去執(zhí)行哪些操作,才能最快的獲取結(jié)果?,F(xiàn)在的圖就變成這樣了:

圖5 查詢優(yōu)化器
5、執(zhí)行器;根據(jù)執(zhí)行計(jì)劃調(diào)用存儲(chǔ)引擎
查詢優(yōu)化器選擇了最優(yōu)的查詢路徑,知道了按照一個(gè)什么樣的順序和步驟去執(zhí)行這個(gè)SQL語句的計(jì)劃,然后就需要執(zhí)行器調(diào)用存儲(chǔ)引擎的接口把SQL語句的邏輯給執(zhí)行了。
比如,執(zhí)行器可能會(huì)先調(diào)用存儲(chǔ)引擎的一個(gè)接口,去獲取user表中的第一行數(shù)據(jù),然后判斷這個(gè)數(shù)據(jù)的id字段是否等于我們期望的值,如果不是的話,就繼續(xù)調(diào)用存儲(chǔ)引擎的接口,獲取user表的下一行數(shù)據(jù)。
基于上述思路,執(zhí)行器,就會(huì)去根據(jù)我們的優(yōu)化器生成的一套執(zhí)行計(jì)劃,不停的調(diào)用存儲(chǔ)引擎的各種接口去完成SQL語句的執(zhí)行。

圖6 執(zhí)行器
6、調(diào)用存儲(chǔ)引擎,真正執(zhí)行SQL語句
執(zhí)行器把執(zhí)行計(jì)劃交給最底層的存儲(chǔ)引擎,就會(huì)真正的執(zhí)行SQL語句了。
執(zhí)行SQL語句,無非是增刪改查數(shù)據(jù),那么數(shù)據(jù)是存放在哪里呢?
數(shù)據(jù)要么是放在內(nèi)存里,要么是放在磁盤上,所有存儲(chǔ)引擎會(huì)按一定的步驟去查詢內(nèi)存緩存的數(shù)據(jù),更新磁盤數(shù)據(jù),等等。
MySQL的架構(gòu)設(shè)計(jì)中,SQL接口,SQL解析器,查詢優(yōu)化器,都是通用的,但存儲(chǔ)引擎是有很多種的。比如常見的innoDB,myisam。
互聯(lián)網(wǎng)公司一般選用innoDB存儲(chǔ)引擎。

圖7 MySQL底層架構(gòu)
搞清楚了MySQL的底層架構(gòu),那么具體執(zhí)行一條SQL時(shí)是怎樣的呢?下節(jié)我們會(huì)講。
有道無術(shù),術(shù)可成;有術(shù)無道,止于術(shù)
歡迎大家關(guān)注Java之道公眾號(hào)
好文章,我在看??
