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