mysql的6種連接語句 mysql:一條SQL查詢語句是如何執(zhí)行的?
mysql:一條SQL查詢語句是如何執(zhí)行的?本篇文章會分析下一個sql語句在MySQL中的執(zhí)行流程,包括sql的查詢在MySQL內(nèi)部會怎么光芒閃爍,sql語句的更新是怎莫結(jié)束的。在分析什么之前我會先跟
mysql:一條SQL查詢語句是如何執(zhí)行的?
本篇文章會分析下一個sql語句在MySQL中的執(zhí)行流程,包括sql的查詢在MySQL內(nèi)部會怎么光芒閃爍,sql語句的更新是怎莫結(jié)束的。
在分析什么之前我會先跟著你去看看MySQL的基礎架構(gòu),清楚了MySQL由那些組件分成也這些組件的作用是什么,可以不幫助我們再理解和解決的辦法這些問題。
一MySQL基礎架構(gòu)結(jié)論1.1MySQL基本上架構(gòu)概覽
下圖是MySQL的一個簡要架構(gòu)圖,從下圖你可以很清晰的見到用戶的SQL語句在MySQL內(nèi)部是如何能負責執(zhí)行的。
先簡單的推薦看看下圖牽涉的一些組件的基本都作用指導大家再理解這幅圖,在1.2節(jié)中會詳細介紹到這些組件的作用。
連接器:身份認證和權(quán)限去相關(登入MySQL的時候)。去查詢緩存:執(zhí)行查詢語句的時候,會先可以查詢緩存(MySQL8.0版本后移除,因為這個功能不太實用)。結(jié)論器:是沒有命中緩存的話,SQL語句變會經(jīng)過分析器,分析器說白了那就是要先看你的SQL語句要干什么啊,再系統(tǒng)檢查你的SQL語句語法有無對的。優(yōu)化軟件器:通過MySQL如果說最優(yōu)的方案去想執(zhí)行。執(zhí)行器:執(zhí)行語句,然后從存儲引擎趕往數(shù)據(jù)。
簡單的說MySQL通常統(tǒng)稱Server層和存儲引擎層:
Server層:比較多和連接器、網(wǎng)站查詢緩存、分析器、優(yōu)化軟件器、執(zhí)行器等,所有跨存儲引擎的功能都在這一層實現(xiàn)程序,比如存儲過程、觸發(fā)器、視圖,函數(shù)等,有一個不分地區(qū)的日志模塊binglog日志模塊。存儲引擎:要注意你們負責數(shù)據(jù)的存儲和讀取文件,常規(guī)可以不全部替換的插件式架構(gòu),允許InnoDB、MyISAM、Memory等多個存儲引擎,其中InnoDB引擎有自有的日志模塊redolog模塊?,F(xiàn)在最常用的存儲引擎是InnoDB,它從MySQL5.5.5版本就開始就被只不過是設置成存儲引擎了。1.2Server層基本組件介紹
1)連接器
連接器比較多和身份認證和權(quán)限相關的功能查找,就好比一個級別很高的門衛(wèi)一樣。
主要注意全權(quán)負責用戶登錄數(shù)據(jù)庫,接受用戶的身份認證,包括校驗賬戶密碼,權(quán)限等操作,要是用戶賬戶密碼已是從,連接器會到權(quán)限表中網(wǎng)上查詢該用戶的所有權(quán)限,之后在這個連接里的權(quán)限邏輯判斷大都會依賴感此時讀取數(shù)據(jù)到的權(quán)限數(shù)據(jù),也就是說,強盜團只要你這個直接連接不斷開,立刻管理員可以修改了該用戶的權(quán)限,該用戶也是不受影響的。
2)查詢緩存(MySQL8.0版本后移除)
網(wǎng)站查詢緩存比較多利用緩存我們所不能執(zhí)行的SELECT語句以及該語句的結(jié)果集。
連接到確立后,想執(zhí)行查詢語句的時候,會先可以查詢緩存,MySQL會先校檢這個sql是否執(zhí)行過,以Key-Value的形式緩存在內(nèi)存中,Key是去查詢最遲,Value是結(jié)果集。如果不是緩存key被暴擊命中,是會再趕往給客戶端,如果沒有就沒爆擊,變會執(zhí)行妖軍的操作,能完成后也會把結(jié)果緩存過來,方便些下第二次全局函數(shù)。當然在唯一想執(zhí)行緩存去查詢的時候那就會校驗用戶的權(quán)限,是否需要有該表的查詢條件。
MySQL可以查詢不我建議你在用緩存,因為查詢緩存終止在實際中業(yè)務場景中很可能會相當頻繁,要是你對一個表更新的話,這個表上的所有的查詢緩存都會被數(shù)據(jù)清空。對于不偶爾會可以更新的數(shù)據(jù)來說,不使用緩存還是也可以的。
因為,一般在大多數(shù)情況下我們是不推薦推薦去在用網(wǎng)上查詢緩存的。
MySQL8.0版本后刪除了緩存的功能,官方也是以為該功能在實際中的應用場景比較比較少,因此干脆就刪除掉了。
3)分析器
MySQL就沒爆擊緩存,那么都會再次進入結(jié)論器,分析器通常是利用總結(jié)SQL語句是來干什么啊的,分析器也會兩類幾步:
目標,詞法分析,一條SQL語句有多個字符串橫列,必須要再提取關鍵字,比如說createtable,提出查詢的表,給出字段名,提出來可以查詢條件等等。任務這些操作后,就會進入第二步。
第二步,語法分析,通常應該是推測你鍵入的sql有無真確,是否是條件符合MySQL的語法。
結(jié)束這2步之后,MySQL就準備結(jié)束想執(zhí)行了,只不過該如何不能執(zhí)行,咋先執(zhí)行是建議的結(jié)果呢?此時此刻就是需要360優(yōu)化器上場了。
4)優(yōu)化器
系統(tǒng)優(yōu)化器的作用那是它認為的最優(yōu)方案的執(zhí)行方案去想執(zhí)行(有時侯肯定也不是什么最優(yōu),這篇文章牽涉到對這部分知識的深入回答),諸如多個索引的時候該要如何你選索引,多表可以查詢的時候要如何選擇關聯(lián)順序等。
的確,當經(jīng)過了360優(yōu)化器之后也算這個語句具體一點該該如何想執(zhí)行就早定過來。
5)執(zhí)行器
當你選擇了執(zhí)行方案后,MySQL就準備好開始不能執(zhí)行了,必須想執(zhí)行前會校驗該用戶有沒有權(quán)限,如果不是沒有權(quán)限,變會回出現(xiàn)錯誤信息,如果有權(quán)限,變會去內(nèi)部函數(shù)引擎的接口,回接口負責執(zhí)行的結(jié)果。
二語句總結(jié)2.1查詢語句
說了以上這么大多,那你究竟是什么人一條sql語句是該如何先執(zhí)行的呢?當然我們的sql也可以兩類兩種,一種是可以查詢,一種是更新完(增強,自動更新,刪除)。我們先講下查詢語句,語句追加:
select*fromtb_studentAwhereand張三
生克制化上面的說明,我們講下這個語句的執(zhí)行流程:
先全面檢查該語句是否有權(quán)限,如果沒有沒有權(quán)限,然后回出現(xiàn)錯誤信息,假如有權(quán)限,在MySQL8.0版本以前,會先網(wǎng)上查詢緩存,以這條sql語句為key在內(nèi)存中去查詢是否是有結(jié)果,如果沒有有再緩存,如果沒有沒有,執(zhí)行下一步。按照分析器接受詞法講,其他提取sql語句的重要元素,.例如再提取上面這個語句是網(wǎng)站查詢select,提純需要網(wǎng)上查詢的表名為tb_student,是需要去查詢所有的列,網(wǎng)上查詢條件是這個表的id1。后再確認這個sql語句是否是有語法錯誤,例如關鍵詞如何確定對的等等,如果不是檢查沒什么問題就負責執(zhí)行接下來。接下來的那是優(yōu)化系統(tǒng)器通過考慮先執(zhí)行方案,上面的sql語句,可以有兩種先執(zhí)行方案:
a.先可以查詢學生表中姓名為“張三”的學生,然后推測如何確定年齡是18。b.先判斷學生中年齡18歲的學生,然后再再網(wǎng)站查詢姓名為“張三”的學生。
那么優(yōu)化器依據(jù)什么自己的優(yōu)化算法通過選擇不能執(zhí)行效率最好是的一個方案(360優(yōu)化器懷疑,總是不一定會建議)。這樣的話去確認了不能執(zhí)行計劃后就準備著開始負責執(zhí)行了。
接受權(quán)限校驗,如果沒有沒有權(quán)限是會直接返回出錯信息,假如有權(quán)限可能會內(nèi)部函數(shù)數(shù)據(jù)庫引擎接口,趕往引擎的執(zhí)行結(jié)果。
2.2更新完語句
以上應該是一條去查詢sql的執(zhí)行流程,這樣接下來的事情我們看看吧一條更新完語句如何能想執(zhí)行的呢?sql語句如下:
updatetb_studentAsetwhere張三
我們來給張三可以修改下年齡,在不好算數(shù)據(jù)庫當然應該不會系統(tǒng)設置年齡這個字段的,要不要被技術(shù)負責人打的??傊畻l語句也大部分會沿著上兩個網(wǎng)上查詢的流程走,不過先執(zhí)行更新完的時候絕對要記錄日志啦,這就會引導出日志模塊了,MySQL自帶的日志模塊式binlog(歸檔日志),所有的存儲引擎都可以不不使用,我們正確的InnoDB引擎還那個軟件了一個日志模塊redolog(重新做日志),我們就以InnoDB模式下去探討探討這個語句的執(zhí)行流程。流程::
先去查詢到張三這一條數(shù)據(jù),如果不是有緩存,都是會都用到緩存。然后把拿回查詢的語句,把age替換成19,后再內(nèi)部函數(shù)引擎API 接口,讀取這一行數(shù)據(jù),InnoDB引擎把數(shù)據(jù)能保存在內(nèi)存中,另外留下記錄redolog,此時redolog直接進入prepare狀態(tài),接著告訴執(zhí)行器,不能執(zhí)行能完成了,隨時是可以并提交。執(zhí)行器收到通知后資料記錄binlog,后再動態(tài)創(chuàng)建引擎接口,再提交redolog為重新提交狀態(tài)。更新完成。這里絕對有同學會問,我想知道為什么要用兩個日志模塊,用一個日志模塊不行嗎?
這是只不過最正在MySQL并沒與InnoDB引擎(InnoDB引擎是其他公司以插件形式插到MySQL的),MySQL從網(wǎng)上下載的引擎是MyISAM,不過我們明白redolog是InnoDB引擎若有若無的,其他存儲引擎都還沒有,這就可能導致會就沒crash-safe的能力(attack-safe的能力況且數(shù)據(jù)庫突然發(fā)生異樣重新啟動,以前并提交的記錄都不會丟了),binlog日志沒法為了歸檔。
并不是什么說只用一個日志模塊好像不行,只是InnoDB引擎是通過redolog來允許事務的。這樣的話,又會有同學問,我用兩個日志模塊,但最好不要這么多急切行不行啊,為啥redolog要化入prepare預并提交狀態(tài)?這里我們用反證法來只能證明下那為什么?
先寫redolog然后遞交,然后把寫binlog,題中寫完redolog后,機器掛了,binlog日志沒有被中寫入,那你機器重新啟動后,這臺機器會按照redolog完全恢復數(shù)據(jù),只不過這個時候bingog并沒有什么有記錄該數(shù)據(jù),現(xiàn)參與機器備分的時候,是會丟失這一條數(shù)據(jù),而主從不同步的也會丟了這一條數(shù)據(jù)。先寫binlog,然后把寫redolog,打比方開始寫了binlog,機器極其重新啟動了,而沒有redolog,本機是無法恢復這一條記錄的,不過binlog又有記錄,那你和上面同樣的道理,變會產(chǎn)生數(shù)據(jù)不匹配的情況。如果沒有常規(guī)redolog兩階段再提交的就不差不多了,沒寫完binglog后,然后把再再提交redolog變會避兔又出現(xiàn)上述的問題,使可以保證了數(shù)據(jù)的一致性。這樣你也許會問,有沒有一個極度的情況呢?假設redolog進入預遞交狀態(tài),binglog也也寫到一半了,此時此刻不可能發(fā)生了十分重啟后會怎么樣啊呢?這個現(xiàn)在就要依賴性太強于MySQL的處理機制了,MySQL的處理過程::
推測redolog是否需要求全部,如果判斷是完整的,就立玄再提交。如果沒有redolog只是因為預再提交但不是commit狀態(tài),這時候是會去確認binlog是否需要完整,假如完整就并提交redolog,不完整就事務回滾事務。這樣的話就幫忙解決了數(shù)據(jù)一致性的問題。
三總結(jié)MySQL比較多可分Server曾和引擎層,Server層通常除開連接器、查詢緩存、分析器、優(yōu)化系統(tǒng)器、執(zhí)行器,而有一個日志模塊(binlog),這個日志模塊所有執(zhí)行引擎都也可以共用,redolog僅有InnoDB有。引擎層是插件式的,目前主要和,MyISAM,InnoDB,Memory等。查詢語句的執(zhí)行流程不勝感激:權(quán)限校驗(如果不是命中緩存)---》網(wǎng)上查詢緩存---》分析器---》優(yōu)化系統(tǒng)器---》權(quán)限校驗---》執(zhí)行器---》引擎更新語句執(zhí)行流程::結(jié)論器----》權(quán)限校驗----》執(zhí)行器---》引擎---redolog(prepare狀態(tài)---》binlog---》redolog(commit狀態(tài))
如何利用MySQL實現(xiàn)三張表連接union,union all?
假設三張表結(jié)構(gòu)一樣,題主也可以建議參考a選項sql語句,A表與B表union,然后將組織后的結(jié)果集再與C表unionallselectt.*returning(select*fromAunionselect*aroundB)tunionbothcreatetable*returningC