
SQL語句執(zhí)行流程與順序原理解析
Oracle語句執(zhí)行流程
第一步:客戶端把語句發(fā)給服務(wù)器端執(zhí)行
當(dāng)我們?cè)诳蛻舳藞?zhí)行SQL語句時(shí),客戶端會(huì)把這條SQL語句發(fā)送給服務(wù)器端,讓服務(wù)器端的進(jìn)程來處理這語句。也就是說,Oracle 客戶端是不會(huì)做任何的操作,他的主要任務(wù)就是把客戶端產(chǎn)生的一些SQL語句發(fā)送給服務(wù)器端。服務(wù)器進(jìn)程從用戶進(jìn)程把信息接收到后, 在PGA 中就要此進(jìn)程分配所需內(nèi)存,存儲(chǔ)相關(guān)的信息,如:在會(huì)話內(nèi)存存儲(chǔ)相關(guān)的登錄信息等。
雖然在客戶端也有一個(gè)數(shù)據(jù)庫進(jìn)程,但是,這個(gè)進(jìn)程的作用跟服務(wù)器上的進(jìn)程作用是不相同的,服務(wù)器上的數(shù)據(jù)庫進(jìn)程才會(huì)對(duì)SQL 語句進(jìn)行相關(guān)的處理。不過,有個(gè)問題需要說明,就是客戶端的進(jìn)程跟服務(wù)器的進(jìn)程是一一對(duì)應(yīng)的。也就是說,在客戶端連接上服務(wù)器后,在客戶端與服務(wù)器端都會(huì)形成一個(gè)進(jìn)程,客戶端上的我們叫做客戶端進(jìn)程,而服務(wù)器上的我們叫做服務(wù)器進(jìn)程。
第二步:語句解析
當(dāng)客戶端把SQL語句傳送到服務(wù)器后,服務(wù)器進(jìn)程會(huì)對(duì)該語句進(jìn)行解析。這個(gè)解析的工作是在服務(wù)器端所進(jìn)行的,解析動(dòng)作又可分為很多小動(dòng)作。
1)查詢高速緩存(library cache)
服務(wù)器進(jìn)程在接到客戶端傳送過來的SQL語句時(shí),不會(huì)直接去數(shù)據(jù)庫查詢。服務(wù)器進(jìn)程把這個(gè)SQL語句的字符轉(zhuǎn)化為ASCII等效數(shù)字碼,接著這個(gè)ASCII碼被傳遞給一個(gè)HASH函數(shù),并返回一個(gè)hash值,然后服務(wù)器進(jìn)程將到shared pool中的library cache(高速緩存)中去查找是否存在相同的hash值。如果存在,服務(wù)器進(jìn)程將使用這條語句已高速緩存在SHARED POOL的library cache中的已分析過的版本來執(zhí)行,省去后續(xù)的解析工作,這便是軟解析。若調(diào)整緩存中不存在,則需要進(jìn)行后面的步驟,這便是硬解析。硬解析通常是昂貴的操作,大約占整個(gè)SQL執(zhí)行的70%左右的時(shí)間,硬解析會(huì)生成執(zhí)行樹,執(zhí)行計(jì)劃,等等。
所以,采用高速數(shù)據(jù)緩存的話,可以提高SQL 語句的查詢效率。其原因有兩方面:一方面是從內(nèi)存中讀取數(shù)據(jù)要比從硬盤中的數(shù)據(jù)文件中讀取數(shù)據(jù)效率要高,另一方面也是因?yàn)楸苊庹Z句解析而節(jié)省了時(shí)間。
不過這里要注意一點(diǎn),這個(gè)數(shù)據(jù)緩存跟有些客戶端軟件的數(shù)據(jù)緩存是兩碼事。有些客戶端軟件為了提高查詢效率,會(huì)在應(yīng)用軟件的客戶端設(shè)置數(shù)據(jù)緩存。由于這些數(shù)據(jù)緩存的存在,可以提高客戶端應(yīng)用軟件的查詢效率。但是,若其他人在服務(wù)器進(jìn)行了相關(guān)的修改,由于應(yīng)用軟件數(shù)據(jù)緩存的存在,導(dǎo)致修改的數(shù)據(jù)不能及時(shí)反映到客戶端上。從這也可以看出,應(yīng)用軟件的數(shù)據(jù)緩存跟數(shù)據(jù)庫服務(wù)器的高速數(shù)據(jù)緩存不是一碼事。
2)語句合法性檢查(data dict cache)
當(dāng)在高速緩存中找不到對(duì)應(yīng)的SQL語句時(shí),則服務(wù)器進(jìn)程就會(huì)開始檢查這條語句的合法性。這里主要是對(duì)SQL語句的語法進(jìn)行檢查,看看其是否合乎語法規(guī)則。如果服務(wù)器進(jìn)程認(rèn)為這條SQL語句不符合語法規(guī)則的時(shí)候,就會(huì)把這個(gè)錯(cuò)誤信息反饋給客戶端。在這個(gè)語法檢查的過程中,不會(huì)對(duì)SQL語句中所包含的表名、列名等等進(jìn)行檢查,只是檢查語法。
3)語言含義檢查(data dict cache)
若SQL 語句符合語法上的定義的話,則服務(wù)器進(jìn)程接下去會(huì)對(duì)語句中涉及的表、索引、視圖等對(duì)象進(jìn)行解析,并對(duì)照數(shù)據(jù)字典檢查這些對(duì)象的名稱以及相關(guān)結(jié)構(gòu),看看這些字段、表、視圖等是否在數(shù)據(jù)庫中。如果表名與列名不準(zhǔn)確的話,則數(shù)據(jù)庫會(huì)就會(huì)反饋錯(cuò)誤信息給客戶端。
所以,有時(shí)候我們寫select語句的時(shí)候,若語法與表名或者列名同時(shí)寫錯(cuò)的話,則系統(tǒng)是先提示說語法錯(cuò)誤,等到語法完全正確后再提示說列名或表名錯(cuò)誤。
4)獲得對(duì)象解析鎖(control structer)
當(dāng)語法、語義都正確后,系統(tǒng)就會(huì)對(duì)我們需要查詢的對(duì)象加鎖。這主要是為了保障數(shù)據(jù)的一致性,防止我們?cè)诓樵兊倪^程中,其他用戶對(duì)這個(gè)對(duì)象的結(jié)構(gòu)發(fā)生改變。
5)數(shù)據(jù)訪問權(quán)限的核對(duì)(data dict cache)
當(dāng)語法、語義通過檢查之后,客戶端還不一定能夠取得數(shù)據(jù),服務(wù)器進(jìn)程還會(huì)檢查連接用戶是否有這個(gè)數(shù)據(jù)訪問的權(quán)限。若用戶不具有數(shù)據(jù)訪問權(quán)限的話,則客戶端就不能夠取得這些數(shù)據(jù)。要注意的是數(shù)據(jù)庫服務(wù)器進(jìn)程先檢查語法與語義,然后才會(huì)檢查訪問權(quán)限。
6)確定最佳執(zhí)行計(jì)劃
當(dāng)語法與語義都沒有問題權(quán)限也匹配,服務(wù)器進(jìn)程還是不會(huì)直接對(duì)數(shù)據(jù)庫文件進(jìn)行查詢。服務(wù)器進(jìn)程會(huì)根據(jù)一定的規(guī)則,對(duì)這條語句進(jìn)行優(yōu)化。在執(zhí)行計(jì)劃開發(fā)之前會(huì)有一步查詢轉(zhuǎn)換,如:視圖合并、子查詢解嵌套、謂語前推及物化視圖重寫查詢等。為了確定采用哪個(gè)執(zhí)行計(jì)劃,Oracle還需要收集統(tǒng)計(jì)信息確定表的訪問聯(lián)結(jié)方法等,最終確定可能的最低成本的執(zhí)行計(jì)劃。
不過要注意,這個(gè)優(yōu)化是有限的。一般在應(yīng)用軟件開發(fā)的過程中,需要對(duì)數(shù)據(jù)庫的sql語句進(jìn)行優(yōu)化,這個(gè)優(yōu)化的作用要大大地大于服務(wù)器進(jìn)程的自我優(yōu)化。
當(dāng)服務(wù)器進(jìn)程的優(yōu)化器確定這條查詢語句的最佳執(zhí)行計(jì)劃后, 就會(huì)將這條SQL語句與執(zhí)行計(jì)劃保存到數(shù)據(jù)高速緩存(library cache)。如此,等以后還有這個(gè)查詢時(shí),就會(huì)省略以上的語法、語義與權(quán)限檢查的步驟,而直接執(zhí)行SQL語句,提高SQL語句處理效率。
第三步:綁定變量賦值
如果SQL語句中使用了綁定變量,掃描綁定變量的聲明,給綁定變量賦值,將變量值帶入執(zhí)行計(jì)劃。若在解析的第一個(gè)步驟,SQL在高速緩沖中存在,則直接跳到該步驟。
第四步:語句執(zhí)行
語句解析只是對(duì)SQL語句的語法進(jìn)行解析,以確保服務(wù)器能夠知道這條語句到底表達(dá)的是什么意思。等到語句解析完成之后,數(shù)據(jù)庫服務(wù)器進(jìn)程才會(huì)真正的執(zhí)行這條SQL語句。
對(duì)于SELECT語句:
1)首先服務(wù)器進(jìn)程要判斷所需數(shù)據(jù)是否在db buffer存在,如果存在且可用,則直接獲取該數(shù)據(jù)而不是從數(shù)據(jù)庫文件中去查詢數(shù)據(jù),同時(shí)根據(jù)LRU 算法增加其訪問計(jì)數(shù);
2)若數(shù)據(jù)不在緩沖區(qū)中,則服務(wù)器進(jìn)程將從數(shù)據(jù)庫文件中查詢相關(guān)數(shù)據(jù),并把這些數(shù)據(jù)放入到數(shù)據(jù)緩沖區(qū)中(buffer cache)。
其中,若數(shù)據(jù)存在于db buffer,其可用性檢查方式為:查看db buffer塊的頭部是否有事務(wù),如果有事務(wù),則從回滾段中讀取數(shù)據(jù);如果沒有事務(wù),則比較select的scn和db buffer塊頭部的scn,如果前者小于后者,仍然要從回滾段中讀取數(shù)據(jù);如果前者大于后者,說明這是一非臟緩存,可以直接讀取這個(gè)db buffer塊的中內(nèi)容。
對(duì)于DML語句(insert、delete、update):
1)檢查所需的數(shù)據(jù)庫是否已經(jīng)被讀取到緩沖區(qū)緩存中。如果已經(jīng)存在緩沖區(qū)緩存,則直接執(zhí)行步驟3;
2)若所需的數(shù)據(jù)庫并不在緩沖區(qū)緩存中,則服務(wù)器將數(shù)據(jù)塊從數(shù)據(jù)文件讀取到緩沖區(qū)緩存中;
3)對(duì)想要修改的表取得的數(shù)據(jù)行鎖定(Row Exclusive Lock),之后對(duì)所需要修改的數(shù)據(jù)行取得獨(dú)占鎖;
4)將數(shù)據(jù)的Redo記錄復(fù)制到redo log buffer;
5)產(chǎn)生數(shù)據(jù)修改的undo數(shù)據(jù);
6)修改db buffer;
7)dbwr將修改寫入數(shù)據(jù)文件;
其中,第2步,服務(wù)器將數(shù)據(jù)從數(shù)據(jù)文件讀取到db buffer經(jīng)經(jīng)歷以下步驟:
1)首先服務(wù)器進(jìn)程將在表頭部請(qǐng)求TM鎖(保證此事務(wù)執(zhí)行過程其他用戶不能修改表的結(jié)構(gòu)),如果成功加TM鎖,再請(qǐng)求一些行級(jí)鎖(TX鎖),如果TM、TX鎖都成功加鎖,那么才開始從數(shù)據(jù)文件讀數(shù)據(jù)。
2)在讀數(shù)據(jù)之前,要先為讀取的文件準(zhǔn)備好buffer空間。服務(wù)器進(jìn)程需要掃描LRU list尋找free db buffer,掃描的過程中,服務(wù)器進(jìn)程會(huì)把發(fā)現(xiàn)的所有已經(jīng)被修改過的db buffer注冊(cè)到dirty list中。如果free db buffer及非臟數(shù)據(jù)塊緩沖區(qū)不足時(shí),會(huì)觸發(fā)dbwr將dirty buffer中指向的緩沖塊寫入數(shù)據(jù)文件,并且清洗掉這些緩沖區(qū)來騰出空間緩沖新讀入的數(shù)據(jù)。
3)找到了足夠的空閑buffer,服務(wù)器進(jìn)程將從數(shù)據(jù)文件中讀入這些行所在的每一個(gè)數(shù)據(jù)塊(db block)(DB BLOCK是ORACLE的最小操作單元,即使你想要的數(shù)據(jù)只是DB BLOCK中很多行中的一行或幾行,ORACLE也會(huì)把這個(gè)DB BLOCK中的所有行都讀入Oracle DB BUFFER中)放入db buffer的空閑的區(qū)域或者覆蓋已被擠出LRU list的非臟數(shù)據(jù)塊緩沖區(qū),并且排列在LRU列表的頭部,也就是在數(shù)據(jù)塊放入db buffer之前也是要先申請(qǐng)db buffer中的鎖存器,成功加鎖后,才能讀數(shù)據(jù)到db buffer。
若數(shù)據(jù)塊已經(jīng)存在于db buffer cache(有時(shí)也稱db buffer或db cache),即使在db buffer中找到一個(gè)沒有事務(wù),而且SCN比自己小的非臟緩存數(shù)據(jù)塊,服務(wù)器進(jìn)程仍然要到表的頭部對(duì)這條記錄申請(qǐng)加鎖,加鎖成功才能進(jìn)行后續(xù)動(dòng)作,如果不成功,則要等待前面的進(jìn)程解鎖后才能進(jìn)行動(dòng)作(這個(gè)時(shí)候阻塞是tx鎖阻塞)。
在記redo日志時(shí),其具體步驟如下:
1)數(shù)據(jù)被讀入到db buffer后,服務(wù)器進(jìn)程將該語句所影響的并被讀入db buffer中的這些行數(shù)據(jù)的rowid及要更新的原值和新值及scn等信息從PGA逐條的寫入redo log buffer中。在寫入redo log buffer之前也要事先請(qǐng)求redo log buffer的鎖存器,成功加鎖后才開始寫入。
2)當(dāng)寫入達(dá)到redo log buffer大小的三分之一或?qū)懭肓窟_(dá)到1M或超過三秒后或發(fā)生檢查點(diǎn)時(shí)或者dbwr之前發(fā)生,都會(huì)觸發(fā)lgwr進(jìn)程把redo log buffer的數(shù)據(jù)寫入磁盤上的redo file文件中(這個(gè)時(shí)候會(huì)產(chǎn)生log file sync等待事件)。
3)已經(jīng)被寫入redo file的redo log buffer所持有的鎖存器會(huì)被釋放,并可被后來的寫入信息覆蓋,redo log buffer是循環(huán)使用的。Redo file也是循環(huán)使用的,當(dāng)一個(gè)redo file寫滿后,lgwr進(jìn)程會(huì)自動(dòng)切換到下一redo file(這個(gè)時(shí)候可能出現(xiàn)log file switch(check point complete)等待事件)。如果是歸檔模式,歸檔進(jìn)程還要將前一個(gè)寫滿的redo file文件的內(nèi)容寫到歸檔日志文件中(這個(gè)時(shí)候可能出現(xiàn)log file switch(archiving needed)。
在為事務(wù)建立undo信息時(shí),其具體步驟如下:
1)在完成本事務(wù)所有相關(guān)的redo log buffer之后,服務(wù)器進(jìn)程開始改寫這個(gè)db buffer的塊頭部事務(wù)列表并寫入scn(一開始scn是寫在redo log buffer中的,并未寫在db buffer)。
2)然后copy包含這個(gè)塊的頭部事務(wù)列表及scn信息的數(shù)據(jù)副本放入回滾段中,將這時(shí)回滾段中的信息稱為數(shù)據(jù)塊的“前映像”,這個(gè)“前映像”用于以后的回滾、恢復(fù)和一致性讀。(回滾段可以存儲(chǔ)在專門的回滾表空間中,這個(gè)表空間由一個(gè)或多個(gè)物理文件組成,并專用于回滾表空間,回滾段也可在其它表空間中的數(shù)據(jù)文件中開辟)。
在修改信息寫入數(shù)據(jù)文件時(shí),其具體步驟如下:
1)改寫db buffer塊的數(shù)據(jù)內(nèi)容,并在塊的頭部寫入回滾段的地址。
2)將db buffer指針放入dirty list。如果一個(gè)行數(shù)據(jù)多次update而未commit,則在回滾段中將會(huì)有多個(gè)“前映像”,除了第一個(gè)“前映像”含有scn信息外,其他每個(gè)"前映像"的頭部都有scn信息和"前前映像"回滾段地址。一個(gè)update只對(duì)應(yīng)一個(gè)scn,然后服務(wù)器進(jìn)程將在dirty list中建立一條指向此db buffer塊的指針(方便dbwr進(jìn)程可以找到dirty list的db buffer數(shù)據(jù)塊并寫入數(shù)據(jù)文件中)。接著服務(wù)器進(jìn)程會(huì)從數(shù)據(jù)文件中繼續(xù)讀入第二個(gè)數(shù)據(jù)塊,重復(fù)前一數(shù)據(jù)塊的動(dòng)作,數(shù)據(jù)塊的讀入、記日志、建立回滾段、修改數(shù)據(jù)塊、放入dirty list。
3)當(dāng)dirty queue的長(zhǎng)度達(dá)到閥值(一般是25%),服務(wù)器進(jìn)程將通知dbwr把臟數(shù)據(jù)寫出,就是釋放db buffer上的鎖存器,騰出更多的free db buffer。前面一直都是在說明oracle一次讀一個(gè)數(shù)據(jù)塊,其實(shí)oracle可以一次讀入多個(gè)數(shù)據(jù)塊(db_file_multiblock_read_count來設(shè)置一次讀入塊的個(gè)數(shù))
當(dāng)執(zhí)行commit時(shí),具體步驟如下:
1)commit觸發(fā)lgwr進(jìn)程,但不強(qiáng)制dbwr立即釋放所有相應(yīng)db buffer塊的鎖。也就是說有可能雖然已經(jīng)commit了,但在隨后的一段時(shí)間內(nèi)dbwr還在寫這條sql語句所涉及的數(shù)據(jù)塊。表頭部的行鎖并不在commit之后立即釋放,而是要等dbwr進(jìn)程完成之后才釋放,這就可能會(huì)出現(xiàn)一個(gè)用戶請(qǐng)求另一用戶已經(jīng)commit的資源不成功的現(xiàn)象。
2)從Commit和dbwr進(jìn)程結(jié)束之間的時(shí)間很短,如果恰巧在commit之后,dbwr未結(jié)束之前斷電,因?yàn)閏ommit之后的數(shù)據(jù)已經(jīng)屬于數(shù)據(jù)文件的內(nèi)容,但這部分文件沒有完全寫入到數(shù)據(jù)文件中。所以需要前滾。由于commit已經(jīng)觸發(fā)lgwr,這些所有未來得及寫入數(shù)據(jù)文件的更改會(huì)在實(shí)例重啟后,由smon進(jìn)程根據(jù)重做日志文件來前滾,完成之前commit未完成的工作(即把更改寫入數(shù)據(jù)文件)。
3)如果未commit就斷電了,因?yàn)閿?shù)據(jù)已經(jīng)在db buffer更改了,沒有commit,說明這部分?jǐn)?shù)據(jù)不屬于數(shù)據(jù)文件。由于dbwr之前觸發(fā)lgwr也就是只要數(shù)據(jù)更改,(肯定要先有l(wèi)og)所有dbwr在數(shù)據(jù)文件上的修改都會(huì)被先一步記入重做日志文件,實(shí)例重啟后,SMON進(jìn)程再根據(jù)重做日志文件來回滾。
其實(shí)smon的前滾回滾是根據(jù)檢查點(diǎn)來完成的,當(dāng)一個(gè)全部檢查點(diǎn)發(fā)生的時(shí)候,首先讓LGWR進(jìn)程將redologbuffer中的所有緩沖(包含未提交的重做信息)寫入重做日志文件,然后讓dbwr進(jìn)程將dbbuffer已提交的緩沖寫入數(shù)據(jù)文件(不強(qiáng)制寫未提交的)。然后更新控制文件和數(shù)據(jù)文件頭部的SCN,表明當(dāng)前數(shù)據(jù)庫是一致的,在相鄰的兩個(gè)檢查點(diǎn)之間有很多事務(wù),有提交和未提交的。
當(dāng)執(zhí)行rollback時(shí),具體步驟如下:
服務(wù)器進(jìn)程會(huì)根據(jù)數(shù)據(jù)文件塊和db buffer中塊的頭部的事務(wù)列表和SCN以及回滾段地址找到回滾段中相應(yīng)的修改前的副本,并且用這些原值來還原當(dāng)前數(shù)據(jù)文件中已修改但未提交的改變。如果有多個(gè)”前映像“,服務(wù)器進(jìn)程會(huì)在一個(gè)“前映像”的頭部找到“前前映像”的回滾段地址,一直找到同一事務(wù)下的最早的一個(gè)“前映像”為止。一旦發(fā)出了commit,用戶就不能rollback,這使得commit后dbwr進(jìn)程還沒有全部完成的后續(xù)動(dòng)作得到了保障。
第五步:提取數(shù)據(jù)
當(dāng)語句執(zhí)行完成之后,查詢到的數(shù)據(jù)還是在服務(wù)器進(jìn)程中,還沒有被傳送到客戶端的用戶進(jìn)程。所以,在服務(wù)器端的進(jìn)程中,有一個(gè)專門負(fù)責(zé)數(shù)據(jù)提取的一段代碼。他的作用就是把查詢到的數(shù)據(jù)結(jié)果返回給用戶端進(jìn)程,從而完成整個(gè)查詢動(dòng)作。
從這整個(gè)查詢處理過程中,我們?cè)跀?shù)據(jù)庫開發(fā)或者應(yīng)用軟件開發(fā)過程中,需要注意以下幾點(diǎn):
一是要了解數(shù)據(jù)庫緩存跟應(yīng)用軟件緩存是兩碼事情。數(shù)據(jù)庫緩存只有在數(shù)據(jù)庫服務(wù)器端才存在,在客戶端是不存在的。只有如此,才能夠保證數(shù)據(jù)庫緩存中的內(nèi)容跟數(shù)據(jù)庫文件的內(nèi)容一致。才能夠根據(jù)相關(guān)的規(guī)則,防止數(shù)據(jù)臟讀、錯(cuò)讀的發(fā)生。而應(yīng)用軟件所涉及的數(shù)據(jù)緩存,由于跟數(shù)據(jù)庫緩存不是一碼事情,所以,應(yīng)用軟件的數(shù)據(jù)緩存雖然可以提高數(shù)據(jù)的查詢效率,但是,卻打破了數(shù)據(jù)一致性的要求,有時(shí)候會(huì)發(fā)生臟讀、錯(cuò)讀等情況的發(fā)生。所以,有時(shí)候,在應(yīng)用軟件上有專門一個(gè)功能,用來在必要的時(shí)候清除數(shù)據(jù)緩存。不過,這個(gè)數(shù)據(jù)緩存的清除,也只是清除本機(jī)上的數(shù)據(jù)緩存,或者說,只是清除這個(gè)應(yīng)用程序的數(shù)據(jù)緩存,而不會(huì)清除數(shù)據(jù)庫的數(shù)據(jù)緩存。
二是絕大部分SQL語句都是按照這個(gè)處理過程處理的。我們DBA或者基于Oracle數(shù)據(jù)庫的開發(fā)人員了解這些語句的處理過程,對(duì)于我們進(jìn)行涉及到SQL語句的開發(fā)與調(diào)試,是非常有幫助的。有時(shí)候,掌握這些處理原則,可以減少我們排錯(cuò)的時(shí)間。特別要注意,數(shù)據(jù)庫是把數(shù)據(jù)查詢權(quán)限的審查放在語法語義的后面進(jìn)行檢查的。所以,有時(shí)會(huì)若光用數(shù)據(jù)庫的權(quán)限控制原則,可能還不能滿足應(yīng)用軟件權(quán)限控制的需要。此時(shí),就需要應(yīng)用軟件的前臺(tái)設(shè)置,實(shí)現(xiàn)權(quán)限管理的要求。而且,有時(shí)應(yīng)用數(shù)據(jù)庫的權(quán)限管理,也有點(diǎn)顯得繁瑣,會(huì)增加服務(wù)器處理的工作量。因此,對(duì)于記錄、字段等的查詢權(quán)限控制,大部分程序涉及人員喜歡在應(yīng)用程序中實(shí)現(xiàn),而不是在數(shù)據(jù)庫上實(shí)現(xiàn)。
Oracle SQL語句執(zhí)行順序
(8)SELECT (9) DISTINCT (11) <select_list>
(1) FROM <left_table>
(3) <join_type> JOIN <right_table>
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) WITH {CUBE | ROLLUP}
(7) HAVING <having_condition>
(10) ORDER BY <order_by_list>
1)FROM:對(duì)FROM子句中的表執(zhí)行笛卡爾積(交叉聯(lián)接),生成虛擬表VT1。
2)ON:對(duì)VT1應(yīng)用ON篩選器,只有那些使為真才被插入到TV2。
3)OUTER (JOIN):如果指定了OUTER JOIN(相對(duì)于CROSS JOIN或INNER JOIN),保留表中未找到匹配的行將作為外部行添加到VT2,生成TV3。如果FROM子句包含兩個(gè)以上的表,則對(duì)上一個(gè)聯(lián)接生成的結(jié)果表和下一個(gè)表重復(fù)執(zhí)行步驟1到步驟3,直到處理完所有的表位置。
4)WHERE:對(duì)TV3應(yīng)用WHERE篩選器,只有使為true的行才插入TV4。
5)GROUP BY:按GROUP BY子句中的列列表對(duì)TV4中的行進(jìn)行分組,生成TV5。
6)CUTE|ROLLUP:把超組插入VT5,生成VT6。
7)HAVING:對(duì)VT6應(yīng)用HAVING篩選器,只有使為true的組插入到VT7。
8)SELECT:處理SELECT列表,產(chǎn)生VT8。
9)DISTINCT:將重復(fù)的行從VT8中刪除,產(chǎn)品VT9。
10)ORDER BY:將VT9中的行按ORDER BY子句中的列列表順序,生成一個(gè)游標(biāo)(VC10),生成表TV11,并返回給調(diào)用者。
以上每個(gè)步驟都會(huì)產(chǎn)生一個(gè)虛擬表,該虛擬表被用作下一個(gè)步驟的輸入。這些虛擬表對(duì)調(diào)用者(客戶端應(yīng)用程序或者外部查詢)不可用。只有最后一步生成的表才會(huì)會(huì)給調(diào)用者。如果沒有在查詢中指定某一個(gè)子句,將跳過相應(yīng)的步驟。
數(shù)據(jù)分析咨詢請(qǐng)掃描二維碼
若不方便掃碼,搜微信號(hào):CDAshujufenxi
LSTM 模型輸入長(zhǎng)度選擇技巧:提升序列建模效能的關(guān)鍵? 在循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)家族中,長(zhǎng)短期記憶網(wǎng)絡(luò)(LSTM)憑借其解決長(zhǎng)序列 ...
2025-07-11CDA 數(shù)據(jù)分析師報(bào)考條件詳解與準(zhǔn)備指南? ? 在數(shù)據(jù)驅(qū)動(dòng)決策的時(shí)代浪潮下,CDA 數(shù)據(jù)分析師認(rèn)證愈發(fā)受到矚目,成為眾多有志投身數(shù) ...
2025-07-11數(shù)據(jù)透視表中兩列相乘合計(jì)的實(shí)用指南? 在數(shù)據(jù)分析的日常工作中,數(shù)據(jù)透視表憑借其強(qiáng)大的數(shù)據(jù)匯總和分析功能,成為了 Excel 用戶 ...
2025-07-11尊敬的考生: 您好! 我們誠(chéng)摯通知您,CDA Level I和 Level II考試大綱將于 2025年7月25日 實(shí)施重大更新。 此次更新旨在確保認(rèn) ...
2025-07-10BI 大數(shù)據(jù)分析師:連接數(shù)據(jù)與業(yè)務(wù)的價(jià)值轉(zhuǎn)化者? ? 在大數(shù)據(jù)與商業(yè)智能(Business Intelligence,簡(jiǎn)稱 BI)深度融合的時(shí)代,BI ...
2025-07-10SQL 在預(yù)測(cè)分析中的應(yīng)用:從數(shù)據(jù)查詢到趨勢(shì)預(yù)判? ? 在數(shù)據(jù)驅(qū)動(dòng)決策的時(shí)代,預(yù)測(cè)分析作為挖掘數(shù)據(jù)潛在價(jià)值的核心手段,正被廣泛 ...
2025-07-10數(shù)據(jù)查詢結(jié)束后:分析師的收尾工作與價(jià)值深化? ? 在數(shù)據(jù)分析的全流程中,“query end”(查詢結(jié)束)并非工作的終點(diǎn),而是將數(shù) ...
2025-07-10CDA 數(shù)據(jù)分析師考試:從報(bào)考到取證的全攻略? 在數(shù)字經(jīng)濟(jì)蓬勃發(fā)展的今天,數(shù)據(jù)分析師已成為各行業(yè)爭(zhēng)搶的核心人才,而 CDA(Certi ...
2025-07-09【CDA干貨】單樣本趨勢(shì)性檢驗(yàn):捕捉數(shù)據(jù)背后的時(shí)間軌跡? 在數(shù)據(jù)分析的版圖中,單樣本趨勢(shì)性檢驗(yàn)如同一位耐心的偵探,專注于從單 ...
2025-07-09year_month數(shù)據(jù)類型:時(shí)間維度的精準(zhǔn)切片? ? 在數(shù)據(jù)的世界里,時(shí)間是最不可或缺的維度之一,而year_month數(shù)據(jù)類型就像一把精準(zhǔn) ...
2025-07-09CDA 備考干貨:Python 在數(shù)據(jù)分析中的核心應(yīng)用與實(shí)戰(zhàn)技巧? ? 在 CDA 數(shù)據(jù)分析師認(rèn)證考試中,Python 作為數(shù)據(jù)處理與分析的核心 ...
2025-07-08SPSS 中的 Mann-Kendall 檢驗(yàn):數(shù)據(jù)趨勢(shì)與突變分析的有力工具? ? ? 在數(shù)據(jù)分析的廣袤領(lǐng)域中,準(zhǔn)確捕捉數(shù)據(jù)的趨勢(shì)變化以及識(shí)別 ...
2025-07-08備戰(zhàn) CDA 數(shù)據(jù)分析師考試:需要多久?如何規(guī)劃? CDA(Certified Data Analyst)數(shù)據(jù)分析師認(rèn)證作為國(guó)內(nèi)權(quán)威的數(shù)據(jù)分析能力認(rèn)證 ...
2025-07-08LSTM 輸出不確定的成因、影響與應(yīng)對(duì)策略? 長(zhǎng)短期記憶網(wǎng)絡(luò)(LSTM)作為循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)的一種變體,憑借獨(dú)特的門控機(jī)制,在 ...
2025-07-07統(tǒng)計(jì)學(xué)方法在市場(chǎng)調(diào)研數(shù)據(jù)中的深度應(yīng)用? 市場(chǎng)調(diào)研是企業(yè)洞察市場(chǎng)動(dòng)態(tài)、了解消費(fèi)者需求的重要途徑,而統(tǒng)計(jì)學(xué)方法則是市場(chǎng)調(diào)研數(shù) ...
2025-07-07CDA數(shù)據(jù)分析師證書考試全攻略? 在數(shù)字化浪潮席卷全球的當(dāng)下,數(shù)據(jù)已成為企業(yè)決策、行業(yè)發(fā)展的核心驅(qū)動(dòng)力,數(shù)據(jù)分析師也因此成為 ...
2025-07-07剖析 CDA 數(shù)據(jù)分析師考試題型:解鎖高效備考與答題策略? CDA(Certified Data Analyst)數(shù)據(jù)分析師考試作為衡量數(shù)據(jù)專業(yè)能力的 ...
2025-07-04SQL Server 字符串截取轉(zhuǎn)日期:解鎖數(shù)據(jù)處理的關(guān)鍵技能? 在數(shù)據(jù)處理與分析工作中,數(shù)據(jù)格式的規(guī)范性是保證后續(xù)分析準(zhǔn)確性的基礎(chǔ) ...
2025-07-04CDA 數(shù)據(jù)分析師視角:從數(shù)據(jù)迷霧中探尋商業(yè)真相? 在數(shù)字化浪潮席卷全球的今天,數(shù)據(jù)已成為企業(yè)決策的核心驅(qū)動(dòng)力,CDA(Certifie ...
2025-07-04CDA 數(shù)據(jù)分析師:開啟數(shù)據(jù)職業(yè)發(fā)展新征程? ? 在數(shù)據(jù)成為核心生產(chǎn)要素的今天,數(shù)據(jù)分析師的職業(yè)價(jià)值愈發(fā)凸顯。CDA(Certified D ...
2025-07-03