- 相關(guān)推薦
Oracle查詢(xún)原理:Select語(yǔ)句
Select語(yǔ)句可以說(shuō)是DBA和數據庫開(kāi)發(fā)者在工作中使用最多的語(yǔ)句之一,但這條語(yǔ)句是如何執行?在Oracle數據庫中又是如何運作的呢?今天我們就從一條簡(jiǎn)單的Select語(yǔ)句開(kāi)始,看看Oracle數據庫后臺的運作機制。這對于我們之后的系統管理與故障排除非常有幫助。
第一步:客戶(hù)端把語(yǔ)句發(fā)給服務(wù)器端執行。
當我們在客戶(hù)端執行select語(yǔ)句時(shí),客戶(hù)端會(huì )把這條SQL語(yǔ)句發(fā)送給服務(wù)器端,讓服務(wù)器端的進(jìn)程來(lái)處理這語(yǔ)句。也就是說(shuō),Oracle客戶(hù)端是不會(huì )做任何的操作,他的主要任務(wù)就是把客戶(hù)端產(chǎn)生的一些SQL語(yǔ)句發(fā)送給服務(wù)器端。雖然在客戶(hù)端也有一個(gè)數據庫進(jìn)程,但是,這個(gè)進(jìn)程的作用跟服務(wù)器上的進(jìn)程作用事不相同的。服務(wù)器上的數據庫進(jìn)程才會(huì )對SQL語(yǔ)句進(jìn)行相關(guān)的處理。不過(guò),有個(gè)問(wèn)題需要說(shuō)明,就是客戶(hù)端的進(jìn)程跟服務(wù)器的進(jìn)程是一一對應的。也就是說(shuō),在客戶(hù)端連接上服務(wù)器后,在客戶(hù)端與服務(wù)器端都會(huì )形成一個(gè)進(jìn)程,客戶(hù)端上的我們叫做客戶(hù)端進(jìn)程;而服務(wù)器上的我們叫做服務(wù)器進(jìn)程。所以,由于所有的SQL語(yǔ)句都是服務(wù)器進(jìn)程執行的,所以,有些人把服務(wù)器進(jìn)程形象地比喻成客戶(hù)端進(jìn)程的“影子”。
第二步:語(yǔ)句解析。
當客戶(hù)端把SQL語(yǔ)句傳送到服務(wù)器后,服務(wù)器進(jìn)程會(huì )對該語(yǔ)句進(jìn)行解析。同理,這個(gè)解析的工作,也是在服務(wù)器端所進(jìn)行的。雖然這只是一個(gè)解析的動(dòng)作,但是,其會(huì )做很多“小動(dòng)作”。
1、查詢(xún)高速緩存。服務(wù)器進(jìn)程在接到客戶(hù)端傳送過(guò)來(lái)的SQL語(yǔ)句時(shí),不會(huì )直接去數據庫查詢(xún)。而是會(huì )先在數據庫的高速緩存中去查找,是否存在相同語(yǔ)句的執行計劃。如果在數據高速緩存中,剛好有其他人使用這個(gè)查詢(xún)語(yǔ)句的話(huà),則服務(wù)器進(jìn)程就會(huì )直接執行這個(gè)SQL語(yǔ)句,省去后續的工作。所以,采用高速數據緩存的話(huà),可以提高SQL語(yǔ)句的查詢(xún)效率。一方面是從內存中讀取數據要比從硬盤(pán)中的數據文件中讀取數據效率要高,另一方面,也是因為這個(gè)語(yǔ)句解析的原因。
不過(guò)這里要注意一點(diǎn),這個(gè)數據緩存跟有些客戶(hù)端軟件的數據緩存是兩碼事。有些客戶(hù)端軟件為了提高查詢(xún)效率,會(huì )在應用軟件的客戶(hù)端設置數據緩存。由于這些數據緩存的存在,可以提高客戶(hù)端應用軟件的查詢(xún)效率。但是,若其他人在服務(wù)器進(jìn)行了相關(guān)的修改,由于應用軟件數據緩存的存在,導致修改的數據不能及時(shí)反映到客戶(hù)端上。從這也可以看出,應用軟件的數據緩存跟數據庫服務(wù)器的高速數據緩存不是一碼事。
2、語(yǔ)句合法性檢查。
當在高速緩存中找不到對應的SQL語(yǔ)句時(shí),則數據庫服務(wù)器進(jìn)程就會(huì )開(kāi)始檢查這條語(yǔ)句的合法性。這里主要是對SQL語(yǔ)句的語(yǔ)法進(jìn)行檢查,看看其是否合乎語(yǔ)法規則。如果服務(wù)器進(jìn)程認為這條SQL語(yǔ)句不符合語(yǔ)法規則的時(shí)候,就會(huì )把這個(gè)錯誤信息,反饋給客戶(hù)端。在這個(gè)語(yǔ)法檢查的過(guò)程中,不會(huì )對SQL語(yǔ)句中所包含的表名、列名等等進(jìn)行SQL他只是語(yǔ)法上的檢查。
3、語(yǔ)言含義檢查。
若SQL語(yǔ)句符合語(yǔ)法上的定義的話(huà),則服務(wù)器進(jìn)程接下去會(huì )對語(yǔ)句中的字段、表等內容進(jìn)行檢查?纯催@些字段、表是否在數據庫中。如果表名與列名不準確的話(huà),則數據庫會(huì )就會(huì )反饋錯誤信息給客戶(hù)端。
所以,有時(shí)候我們寫(xiě)select語(yǔ)句的時(shí)候,若語(yǔ)法與表名或者列名同時(shí)寫(xiě)錯的話(huà),則系統是先提示說(shuō)語(yǔ)法錯誤,等到語(yǔ)法完全正確后,再提示說(shuō)列名或表名錯誤。若能夠掌握這個(gè)順序的話(huà),則在應用程序排錯的時(shí)候,可以節省時(shí)間。
4、獲得對象解析鎖。
當語(yǔ)法、語(yǔ)義都正確后,系統就會(huì )對我們需要查詢(xún)的對象加鎖。這主要是為了保障數據的一致性,防止我們在查詢(xún)的過(guò)程中,其他用戶(hù)對這個(gè)對象的結構發(fā)生改變。對于加鎖的原理與方法,我在其他文章中已經(jīng)有專(zhuān)門(mén)敘述,在這里就略過(guò)不談了。
5、數據訪(fǎng)問(wèn)權限的核對。
當語(yǔ)法、語(yǔ)義通過(guò)檢查之后,客戶(hù)端還不一定能夠取得數據。服務(wù)器進(jìn)程還會(huì )檢查,你所連接的用戶(hù)是否有這個(gè)數據訪(fǎng)問(wèn)的權限。若你連接上服務(wù)器的用戶(hù)不具有數據訪(fǎng)問(wèn)權限的話(huà),則客戶(hù)端就不能夠取得這些數據。故,有時(shí)候我們查詢(xún)數據的時(shí)候,辛辛苦苦地把SQL語(yǔ)句寫(xiě)好、編譯通過(guò),但是,最后系統返回個(gè)“沒(méi)有權限訪(fǎng)問(wèn)數據”的錯誤信息,讓我們氣半死。這在前端應用軟件開(kāi)發(fā)調試的過(guò)程中,可能會(huì )碰到。所以,要注意這個(gè)問(wèn)題,數據庫服務(wù)器進(jìn)程先檢查語(yǔ)法與語(yǔ)義,然后才會(huì )檢查訪(fǎng)問(wèn)權限。
6、確定最佳執行計劃。
當語(yǔ)句與語(yǔ)法都沒(méi)有問(wèn)題,權限也匹配的話(huà),服務(wù)器進(jìn)程還是不會(huì )直接對數據庫文件進(jìn)行查詢(xún)。服務(wù)器進(jìn)程會(huì )根據一定的規則,對這條語(yǔ)句進(jìn)行優(yōu)化。不過(guò)要注意,這個(gè)優(yōu)化是有限的。一般在應用軟件開(kāi)發(fā)的過(guò)程中,需要對數據庫的sql語(yǔ)言進(jìn)行優(yōu)化,這個(gè)優(yōu)化的作用要大大地大于服務(wù)器進(jìn)程的自我優(yōu)化。所以,一般在應用軟件開(kāi)發(fā)的時(shí)候,數據庫的優(yōu)化是少不了的。
當服務(wù)器進(jìn)程的優(yōu)化器確定這條查詢(xún)語(yǔ)句的最佳執行計劃后,就會(huì )將這條SQL語(yǔ)句與執行計劃保存到數據高速緩存。如此的話(huà),等以后還有這個(gè)查詢(xún)時(shí),就會(huì )省略以上的語(yǔ)法、語(yǔ)義與權限檢查的步驟,而直接執行SQL語(yǔ)句,提高SQL語(yǔ)句處理效率。
第三步:語(yǔ)句執行。
語(yǔ)句解析只是對SQL語(yǔ)句的語(yǔ)法進(jìn)行解析,以確保服務(wù)器能夠知道這條語(yǔ)句到底表達的是什么意思。等到語(yǔ)句解析完成之后,數據庫服務(wù)器進(jìn)程才會(huì )真正的執行這條SQL語(yǔ)句。
這個(gè)語(yǔ)句執行也分兩種情況。一是若被選擇行所在的數據塊已經(jīng)被讀取到數據緩沖區的話(huà),則服務(wù)器進(jìn)程會(huì )直接把這個(gè)數據傳遞給客戶(hù)端,而不是從數據庫文件中去查詢(xún)數據。若數據不在緩沖區中,則服務(wù)器進(jìn)程將從數據庫文件中查詢(xún)相關(guān)數據,并把這些數據放入到數據緩沖區中。
這里仍然要注意一點(diǎn),就是Oracle數據庫中,定義了很多種類(lèi)的高速緩存。像上面所說(shuō)的SQL語(yǔ)句緩存與現在講的數據緩存。我們在學(xué)習數據庫的時(shí)候,需要對這些緩存有一個(gè)清晰的認識,并了解各個(gè)種類(lèi)緩存的作用。這對于我們后續數據庫維護與數據庫優(yōu)化是非常有用的。
第四步:提取數據。
當語(yǔ)句執行完成之后,查詢(xún)到的數據還是在服務(wù)器進(jìn)程中,還沒(méi)有被傳送到客戶(hù)端的用戶(hù)進(jìn)程。所以,在服務(wù)器端的進(jìn)程中,有一個(gè)專(zhuān)門(mén)負責數據提取的一段代碼。他的作用就是把查詢(xún)到的數據結果返回給用戶(hù)端進(jìn)程,從而完成整個(gè)查詢(xún)動(dòng)作。
從這整個(gè)查詢(xún)處理過(guò)程中,我們在數據庫開(kāi)發(fā)或者應用軟件開(kāi)發(fā)過(guò)程中,需要注意以下幾點(diǎn):
一是要了解數據庫緩存跟應用軟件緩存是兩碼事情。數據庫緩存只有在數據庫服務(wù)器端才存在,在客戶(hù)端是不存在的。只有如此,才能夠保證數據庫緩存中的內容跟數據庫文件的內容一致。才能夠根據相關(guān)的規則,防止數據臟讀、錯讀的發(fā)生。而應用軟件所涉及的數據緩存,由于跟數據庫緩存不是一碼事情,所以,應用軟件的數據緩存雖然可以提高數據的查詢(xún)效率,但是,卻打破了數據一致性的要求,有時(shí)候會(huì )發(fā)生臟讀、錯讀等情況的發(fā)生。所以,有時(shí)候,在應用軟件上有專(zhuān)門(mén)一個(gè)功能,用來(lái)在必要的時(shí)候清除數據緩存。不過(guò),這個(gè)數據緩存的清除,也只是清除本機上的數據緩存,或者說(shuō),只是清除這個(gè)應用程序的數據緩存,而不會(huì )清除數據庫的數據緩存。
二是絕大部分SQL語(yǔ)句都是按照這個(gè)處理過(guò)程處理的。我們DBA或者基于Oracle數據庫的開(kāi)發(fā)人員了解這些語(yǔ)句的處理過(guò)程,對于我們進(jìn)行涉及到SQL語(yǔ)句的開(kāi)發(fā)與調試,是非常有幫助的。有時(shí)候,掌握這些處理原則,可以減少我們排錯的時(shí)間。特別要注意,數據庫是把數據查詢(xún)權限的審查放在語(yǔ)法語(yǔ)義的后面進(jìn)行檢查的。所以,有時(shí)會(huì )若光用數據庫的權限控制原則,可能還不能滿(mǎn)足應用軟件權限控制的需要。此時(shí),就需要應用軟件的前臺設置,實(shí)現權限管理的要求。而且,有時(shí)應用數據庫的權限管理,也有點(diǎn)顯得繁瑣,會(huì )增加服務(wù)器處理的工作量。因此,對于記錄、字段等的查詢(xún)權限控制,大部分程序涉及人員喜歡在應用程序中實(shí)現,而不是在數據庫上實(shí)現。
【Oracle查詢(xún)原理:Select語(yǔ)句】相關(guān)文章:
Oracle數據庫基礎知識:SELECT語(yǔ)句01-23
oracle的sql語(yǔ)句01-21
Oracle 數據庫查詢(xún)小技巧03-21
oracle數據庫基本語(yǔ)句02-08
Oracle數據庫語(yǔ)句大全12-21
ORACLE數據庫操作基本語(yǔ)句03-06