一條SQL語(yǔ)句是怎樣執(zhí)行的

有一個(gè)數(shù)據(jù)表炼蹦,只有ID屬性列,以select * from T where ID = 10為例

先看一張Mysql的架構(gòu)圖显设,如下:


image.png

連接器

第一步框弛,需要連接到數(shù)據(jù)庫(kù)上,這個(gè)時(shí)候接待我們的就是連接器捕捂,連接器負(fù)責(zé)根客戶端建立連接瑟枫、獲取權(quán)限、維持和管理連接
一般連接命令如下:
mysql -h$ip -P$port -u$user -p
輸完命令后指攒,就需要在交互對(duì)話框輸入密碼慷妙。
連接命令中的mysql是客戶端工具,用來(lái)根服務(wù)器建立連接允悦,在完成經(jīng)典的TCP握手后膝擂,連接器就開(kāi)始認(rèn)證我們的身份,這個(gè)時(shí)候用的就是輸入的用戶名和密碼隙弛。

  1. 如果用戶名或者這密碼不對(duì)架馋,會(huì)產(chǎn)生一個(gè)"Access denied for user"的錯(cuò)誤,然后客戶端程序執(zhí)行結(jié)束
  2. 如果用戶名密碼認(rèn)證通過(guò)全闷,連接器會(huì)到權(quán)限表里面查出你擁有的權(quán)限叉寂,之后再鏈接里的權(quán)限判斷邏輯,都將以來(lái)此時(shí)讀到的權(quán)限总珠。這就意味著屏鳍,一個(gè)用戶成功建立連接后,即便管理員對(duì)這個(gè)用戶的權(quán)限做了修改局服,也不會(huì)影響到已經(jīng)存在的連接權(quán)限钓瞭。修改完成后,只有再次建立新的連接才會(huì)使用新的權(quán)限設(shè)置淫奔。
    連接完成后山涡,如果你沒(méi)有后續(xù)的動(dòng)作,這個(gè)連接就處于空閑狀態(tài)唆迁,可以使用show processlist查看佳鳖,其中Command為Sleep對(duì)的表示,現(xiàn)在這個(gè)連接是空閑的媒惕。
    如果客戶端太長(zhǎng)沒(méi)動(dòng)靜,連接器就會(huì)自動(dòng)將它斷開(kāi)来庭,這個(gè)參數(shù)時(shí)候wait_timeout控制的妒蔚。默認(rèn)是8小時(shí)

如果在連接被斷開(kāi)之后,客戶端再次發(fā)送請(qǐng)求的話,就會(huì)收到一個(gè)Lost connection toMYSQL server during query肴盏。這個(gè)時(shí)候需要重連科盛。

數(shù)據(jù)庫(kù)里面,長(zhǎng)連接是指連接成功后菜皂,如果客戶端持續(xù)有請(qǐng)求贞绵,則一直使用同一個(gè)連接。短鏈接則是指每次執(zhí)行完很少的幾次查詢就斷開(kāi)連接恍飘,下次查詢尋再重新連級(jí)一個(gè)
在全部使用長(zhǎng)連接之后榨崩,MYSQ占用內(nèi)存漲的特別快,這是因?yàn)镸YSQL在執(zhí)行過(guò)程中臨時(shí)使用的內(nèi)存是管理在連接對(duì)象倆面的章母。這些資源只有在斷開(kāi)的時(shí)候才會(huì)釋放母蛛。所以如果行i攔截積累下來(lái)可能會(huì)導(dǎo)致占用內(nèi)存太大,從而被系統(tǒng)強(qiáng)行殺掉(OOM Out Of Memory)乳怎,從表現(xiàn)看來(lái)就是MYSQL異常重啟了彩郊。
解決方案如下:

  1. 定期斷開(kāi)長(zhǎng)連接。使用一段時(shí)間或者程序里面判斷執(zhí)行過(guò)一個(gè)占用內(nèi)存的大查詢之后斷開(kāi)連接蚪缀。
  2. 如果使用5.7+版本之后秫逝,可以在每次執(zhí)行一個(gè)較大的操作之后,通過(guò)mysql_reset_connection來(lái)重新初始化連接資源询枚。這個(gè)過(guò)程不需要重連和重新做權(quán)限驗(yàn)證违帆,但是會(huì)將連接恢復(fù)到剛剛創(chuàng)建完的狀態(tài)

查詢緩存

連接建立完之后,就可以執(zhí)行select雅居樂(lè)哩盲,執(zhí)行邏輯會(huì)來(lái)到第二步:查詢緩存痹仙。
Mysql拿到一個(gè)查詢請(qǐng)求之后,會(huì)先到查詢緩存看看饵撑,之前是不是執(zhí)行過(guò)這條sql語(yǔ)句撩笆。執(zhí)行執(zhí)行語(yǔ)句及其結(jié)果會(huì)以Key-value對(duì)的形式,被直接緩存到內(nèi)存中抒线。key是查詢的語(yǔ)句班巩,value是結(jié)果,如果能夠直接在緩存中找到查詢尋語(yǔ)句嘶炭,那么會(huì)直接將value返回
如果不存在會(huì)繼續(xù)執(zhí)行后面的階段 抱慌,執(zhí)行完成之后結(jié)果會(huì)被存到緩存中,雖然查詢尋緩存命中之后眨猎,效率極高抑进,但總的來(lái)說(shuō)弊大于利
緩存的失效非常頻繁,一位內(nèi)只要對(duì)一個(gè)表有更新睡陪,這個(gè)表的所有查詢緩存都會(huì)被清空
從mysql.8.0開(kāi)始將查詢緩存整塊功能都刪掉了

分析器

如果沒(méi)有名中查詢緩存寺渗,就要開(kāi)始真正執(zhí)行語(yǔ)句了匿情。首先mysql需要知道我們是要做什么,因此需要對(duì)SQL語(yǔ)句做解析信殊。分析器首先會(huì)做“詞法分析”炬称,SQL語(yǔ)句是由多個(gè)字符串和空格組成的,MySQL需要識(shí)別出里面的字符串分別是什么表示什么涡拘。做完了這些后就會(huì)進(jìn)行語(yǔ)法分析玲躯,根據(jù)詞法分析的結(jié)果,語(yǔ)法分析器會(huì)根據(jù)語(yǔ)法規(guī)則鳄乏,判斷這個(gè)sql語(yǔ)句是否滿足mysql語(yǔ)法
在分析語(yǔ)法的時(shí)候同時(shí)會(huì)分析索要查詢的列是否存在跷车,因?yàn)楸斫Y(jié)構(gòu)并不是需要打開(kāi)表才能看到的,因此對(duì)列是否存在的分析也是在這一步完成的

優(yōu)化器

經(jīng)過(guò)了分析器汞窗,mysql就能知道需要做什么了姓赤、優(yōu)化器是在表里面有多個(gè)索引的時(shí)候,決定使用哪個(gè)索引仲吏;或者在一個(gè)語(yǔ)句有多表關(guān)聯(lián)(join)的時(shí)候不铆,決定各個(gè)表的連接順序,如下語(yǔ)句

select * from t1 join using(ID) where t1.c=10 and t2.d = 20;

既可以先從t1表里面取出c=10的記錄ID值裹唆,再根據(jù)t2里面d值怕判斷是否等于20
也可以先從t2表里面取出d=20的記錄id值誓斥,在根據(jù)id值關(guān)聯(lián)到t1,在判斷t1里面的c是否等于10
這兩種執(zhí)行方法的邏輯結(jié)果是一樣的许帐,但是執(zhí)行的效率會(huì)有不同劳坑,而優(yōu)化器的作用是決定選擇使用哪一個(gè)方案。
優(yōu)化器階段完成后成畦,這個(gè)語(yǔ)句的執(zhí)行方案就確定下來(lái)了距芬,接下來(lái)進(jìn)入執(zhí)行器階段。

執(zhí)行器

mysql通過(guò)分析器知道要做什么循帐,通過(guò)優(yōu)化器知道要怎么做框仔,接下來(lái)就進(jìn)入執(zhí)行器,開(kāi)始執(zhí)行SQL語(yǔ)句
開(kāi)始執(zhí)行的時(shí)候拄养,要先判斷一下當(dāng)前用戶是否有對(duì)這個(gè)表T的執(zhí)行查詢權(quán)限离斩,但是如果在命中緩存的時(shí)候,會(huì)在將緩存放回結(jié)果的時(shí)候進(jìn)行權(quán)限驗(yàn)證
如果有權(quán)限那么就打開(kāi)表繼續(xù)執(zhí)行瘪匿,跛梗。打開(kāi)表的時(shí)候,執(zhí)行器就會(huì)根據(jù)表的殷勤定義棋弥,去使用引擎提供的接口核偿。
比如本例中,ID字段沒(méi)有索引顽染,那么執(zhí)行器的執(zhí)行流程如下:

  1. 調(diào)用InnoDB引擎接口獲取表的第一行根據(jù)條件判斷ID是否為10宪祥,如果不是則跳過(guò)聂薪,如果是則將這一行緩存到結(jié)果集中
  2. 調(diào)取引擎接口獲取下一行,直到這個(gè)表的最后一行蝗羊。
  3. 執(zhí)行器將上述遍歷過(guò)程中所有滿足條件的記錄集作為結(jié)果集返回給客戶端。
    至此一個(gè)語(yǔ)句就執(zhí)行完了
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末仁锯,一起剝皮案震驚了整個(gè)濱河市耀找,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌业崖,老刑警劉巖野芒,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異双炕,居然都是意外死亡狞悲,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門妇斤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)摇锋,“玉大人,你說(shuō)我怎么就攤上這事站超≥┧。” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵死相,是天一觀的道長(zhǎng)融求。 經(jīng)常有香客問(wèn)我,道長(zhǎng)算撮,這世上最難降的妖魔是什么生宛? 我笑而不...
    開(kāi)封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮肮柜,結(jié)果婚禮上陷舅,老公的妹妹穿的比我還像新娘。我一直安慰自己素挽,他們只是感情好蔑赘,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著预明,像睡著了一般缩赛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上撰糠,一...
    開(kāi)封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天酥馍,我揣著相機(jī)與錄音,去河邊找鬼阅酪。 笑死旨袒,一個(gè)胖子當(dāng)著我的面吹牛汁针,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播砚尽,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼施无,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了必孤?” 一聲冷哼從身側(cè)響起猾骡,我...
    開(kāi)封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎敷搪,沒(méi)想到半個(gè)月后兴想,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赡勘,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年嫂便,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闸与。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡毙替,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出几迄,到底是詐尸還是另有隱情蔚龙,我是刑警寧澤,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布映胁,位于F島的核電站木羹,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏解孙。R本人自食惡果不足惜坑填,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望弛姜。 院中可真熱鬧脐瑰,春花似錦、人聲如沸廷臼。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)荠商。三九已至寂恬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間莱没,已是汗流浹背初肉。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留饰躲,地道東北人牙咏。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓臼隔,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親妄壶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子摔握,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容