導(dǎo)讀:Oracle的后臺運作原理是什么?我們的一條命令是如何被執(zhí)行的?今天我們就從一條簡單的Select語句開始,看看Oracle數(shù)據(jù)庫后臺的運作機制。
為鹽邊等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計制作服務(wù),及鹽邊網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為網(wǎng)站設(shè)計制作、成都網(wǎng)站制作、鹽邊網(wǎng)站設(shè)計,以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會得到認(rèn)可,從而選擇與我們長期合作。這樣,我們也可以走得更遠(yuǎn)!
Select語句可以說是DBA和數(shù)據(jù)庫開發(fā)者在工作中使用最多的語句之一,但這條語句是如何執(zhí)行?在Oracle數(shù)據(jù)庫中又是如何運作的呢?今天我們就從一條簡單的Select語句開始,看看Oracle數(shù)據(jù)庫后臺的運作機制。這對于我們之后的系統(tǒng)管理與故障排除非常有幫助。
第一步:客戶端把語句發(fā)給服務(wù)器端執(zhí)行
當(dāng)我們在客戶端執(zhí)行select語句時,客戶端會把這條SQL語句發(fā)送給服務(wù)器端,讓服務(wù)器端的進程來處理這語句。也就是說,Oracle客戶端是不會做任何的操作,他的主要任務(wù)就是把客戶端產(chǎn)生的一些SQL語句發(fā)送給服務(wù)器端。雖然在客戶端也有一個數(shù)據(jù)庫進程,但是,這個進程的作用跟服務(wù)器上的進程作用事不相同的。服務(wù)器上的數(shù)據(jù)庫進程才會對SQL語句進行相關(guān)的處理。不過,有個問題需要說明,就是客戶端的進程跟服務(wù)器的進程是一一對應(yīng)的。也就是說,在客戶端連接上服務(wù)器后,在客戶端與服務(wù)器端都會形成一個進程,客戶端上的我們叫做客戶端進程;而服務(wù)器上的我們叫做服務(wù)器進程。所以,由于所有的SQL語句都是服務(wù)器進程執(zhí)行的,所以,有些人把服務(wù)器進程形象地比喻成客戶端進程的“影子”。
第二步:語句解析
當(dāng)客戶端把SQL語句傳送到服務(wù)器后,服務(wù)器進程會對該語句進行解析。同理,這個解析的工作,也是在服務(wù)器端所進行的。雖然這只是一個解析的動作,但是,其會做很多“小動作”。
1. 查詢高速緩存。服務(wù)器進程在接到客戶端傳送過來的SQL語句時,不會直接去數(shù)據(jù)庫查詢。而是會先在數(shù)據(jù)庫的高速緩存中去查找,是否存在相同語句的執(zhí)行計劃。如果在數(shù)據(jù)高速緩存中,剛好有其他人使用這個查詢語句的話,則服務(wù)器進程就會直接執(zhí)行這個SQL語句,省去后續(xù)的工作。所以,采用高速數(shù)據(jù)緩存的話,可以提高SQL語句的查詢效率。一方面是從內(nèi)存中讀取數(shù)據(jù)要比從硬盤中的數(shù)據(jù)文件中讀取數(shù)據(jù)效率要高,另一方面,也是因為這個語句解析的原因。
不過這里要注意一點,這個數(shù)據(jù)緩存跟有些客戶端軟件的數(shù)據(jù)緩存是兩碼事。有些客戶端軟件為了提高查詢效率,會在應(yīng)用軟件的客戶端設(shè)置數(shù)據(jù)緩存。由于這些數(shù)據(jù)緩存的存在,可以提高客戶端應(yīng)用軟件的查詢效率。但是,若其他人在服務(wù)器進行了相關(guān)的修改,由于應(yīng)用軟件數(shù)據(jù)緩存的存在,導(dǎo)致修改的數(shù)據(jù)不能及時反映到客戶端上。從這也可以看出,應(yīng)用軟件的數(shù)據(jù)緩存跟數(shù)據(jù)庫服務(wù)器的高速數(shù)據(jù)緩存不是一碼事。
2. 語句合法性檢查。當(dāng)在高速緩存中找不到對應(yīng)的SQL語句時,則數(shù)據(jù)庫服務(wù)器進程就會開始檢查這條語句的合法性。這里主要是對SQL語句的語法進行檢查,看看其是否合乎語法規(guī)則。如果服務(wù)器進程認(rèn)為這條SQL語句不符合語法規(guī)則的時候,就會把這個錯誤信息,反饋給客戶端。在這個語法檢查的過程中,不會對SQL語句中所包含的表名、列名等等進行SQL他只是語法上的檢查。
3. 語言含義檢查。若SQL語句符合語法上的定義的話,則服務(wù)器進程接下去會對語句中的字段、表等內(nèi)容進行檢查??纯催@些字段、表是否在數(shù)據(jù)庫中。如果表名與列名不準(zhǔn)確的話,則數(shù)據(jù)庫會就會反饋錯誤信息給客戶端。
所以,有時候我們寫select語句的時候,若語法與表名或者列名同時寫錯的話,則系統(tǒng)是先提示說語法錯誤,等到語法完全正確后,再提示說列名或表名錯誤。若能夠掌握這個順序的話,則在應(yīng)用程序排錯的時候,可以節(jié)省時間。
4. 獲得對象解析鎖。當(dāng)語法、語義都正確后,系統(tǒng)就會對我們需要查詢的對象加鎖。這主要是為了保障數(shù)據(jù)的一致性,防止我們在查詢的過程中,其他用戶對這個對象的結(jié)構(gòu)發(fā)生改變。對于加鎖的原理與方法,我在其他文章中已經(jīng)有專門敘述,在這里就略過不談了。
5. 數(shù)據(jù)訪問權(quán)限的核對。當(dāng)語法、語義通過檢查之后,客戶端還不一定能夠取得數(shù)據(jù)。服務(wù)器進程還會檢查,你所連接的用戶是否有這個數(shù)據(jù)訪問的權(quán)限。若你連接上服務(wù)器的用戶不具有數(shù)據(jù)訪問權(quán)限的話,則客戶端就不能夠取得這些數(shù)據(jù)。故,有時候我們查詢數(shù)據(jù)的時候,辛辛苦苦地把SQL語句寫好、編譯通過,但是,最后系統(tǒng)返回個 “沒有權(quán)限訪問數(shù)據(jù)”的錯誤信息,讓我們氣半死。這在前端應(yīng)用軟件開發(fā)調(diào)試的過程中,可能會碰到。所以,要注意這個問題,數(shù)據(jù)庫服務(wù)器進程先檢查語法與語義,然后才會檢查訪問權(quán)限。
6. 確定最佳執(zhí)行計劃。當(dāng)語句與語法都沒有問題,權(quán)限也匹配的話,服務(wù)器進程還是不會直接對數(shù)據(jù)庫文件進行查詢。服務(wù)器進程會根據(jù)一定的規(guī)則,對這條語句進行優(yōu)化。不過要注意,這個優(yōu)化是有限的。一般在應(yīng)用軟件開發(fā)的過程中,需要對數(shù)據(jù)庫的sql語言進行優(yōu)化,這個優(yōu)化的作用要大大地大于服務(wù)器進程的自我優(yōu)化。所以,一般在應(yīng)用軟件開發(fā)的時候,數(shù)據(jù)庫的優(yōu)化是少不了的。
當(dāng)服務(wù)器進程的優(yōu)化器確定這條查詢語句的最佳執(zhí)行計劃后,就會將這條SQL語句與執(zhí)行計劃保存到數(shù)據(jù)高速緩存。如此的話,等以后還有這個查詢時,就會省略以上的語法、語義與權(quán)限檢查的步驟,而直接執(zhí)行SQL語句,提高SQL語句處理效率。
第三步:語句執(zhí)行
語句解析只是對SQL語句的語法進行解析,以確保服務(wù)器能夠知道這條語句到底表達(dá)的是什么意思。等到語句解析完成之后,數(shù)據(jù)庫服務(wù)器進程才會真正的執(zhí)行這條SQL語句。
這個語句執(zhí)行也分兩種情況。一是若被選擇行所在的數(shù)據(jù)塊已經(jīng)被讀取到數(shù)據(jù)緩沖區(qū)的話,則服務(wù)器進程會直接把這個數(shù)據(jù)傳遞給客戶端,而不是從數(shù)據(jù)庫文件中去查詢數(shù)據(jù)。若數(shù)據(jù)不在緩沖區(qū)中,則服務(wù)器進程將從數(shù)據(jù)庫文件中查詢相關(guān)數(shù)據(jù),并把這些數(shù)據(jù)放入到數(shù)據(jù)緩沖區(qū)中。
這里仍然要注意一點,就是Oracle數(shù)據(jù)庫中,定義了很多種類的高速緩存。像上面所說的SQL語句緩存與現(xiàn)在講的數(shù)據(jù)緩存。我們在學(xué)習(xí)數(shù)據(jù)庫的時候,需要對這些緩存有一個清晰的認(rèn)識,并了解各個種類緩存的作用。這對于我們后續(xù)數(shù)據(jù)庫維護與數(shù)據(jù)庫優(yōu)化是非常有用的。
第四步:提取數(shù)據(jù)
當(dāng)語句執(zhí)行完成之后,查詢到的數(shù)據(jù)還是在服務(wù)器進程中,還沒有被傳送到客戶端的用戶進程。所以,在服務(wù)器端的進程中,有一個專門負(fù)責(zé)數(shù)據(jù)提取的一段代碼。他的作用就是把查詢到的數(shù)據(jù)結(jié)果返回給用戶端進程,從而完成整個查詢動作。
從這整個查詢處理過程中,我們在數(shù)據(jù)庫開發(fā)或者應(yīng)用軟件開發(fā)過程中,需要注意以下幾點:
一是要了解數(shù)據(jù)庫緩存跟應(yīng)用軟件緩存是兩碼事情。數(shù)據(jù)庫緩存只有在數(shù)據(jù)庫服務(wù)器端才存在,在客戶端是不存在的。只有如此,才能夠保證數(shù)據(jù)庫緩存中的內(nèi)容跟數(shù)據(jù)庫文件的內(nèi)容一致。才能夠根據(jù)相關(guān)的規(guī)則,防止數(shù)據(jù)臟讀、錯讀的發(fā)生。而應(yīng)用軟件所涉及的數(shù)據(jù)緩存,由于跟數(shù)據(jù)庫緩存不是一碼事情,所以,應(yīng)用軟件的數(shù)據(jù)緩存雖然可以提高數(shù)據(jù)的查詢效率,但是,卻打破了數(shù)據(jù)一致性的要求,有時候會發(fā)生臟讀、錯讀等情況的發(fā)生。所以,有時候,在應(yīng)用軟件上有專門一個功能,用來在必要的時候清除數(shù)據(jù)緩存。不過,這個數(shù)據(jù)緩存的清除,也只是清除本機上的數(shù)據(jù)緩存,或者說,只是清除這個應(yīng)用程序的數(shù)據(jù)緩存,而不會清除數(shù)據(jù)庫的數(shù)據(jù)緩存。
二是絕大部分SQL語句都是按照這個處理過程處理的。我們DBA或者基于Oracle數(shù)據(jù)庫的開發(fā)人員了解這些語句的處理過程,對于我們進行涉及到SQL語句的開發(fā)與調(diào)試,是非常有幫助的。有時候,掌握這些處理原則,可以減少我們排錯的時間。特別要注意,數(shù)據(jù)庫是把數(shù)據(jù)查詢權(quán)限的審查放在語法語義的后面進行檢查的。所以,有時會若光用數(shù)據(jù)庫的權(quán)限控制原則,可能還不能滿足應(yīng)用軟件權(quán)限控制的需要。此時,就需要應(yīng)用軟件的前臺設(shè)置,實現(xiàn)權(quán)限管理的要求。而且,有時應(yīng)用數(shù)據(jù)庫的權(quán)限管理,也有點顯得繁瑣,會增加服務(wù)器處理的工作量。因此,對于記錄、字段等的查詢權(quán)限控制,大部分程序涉及人員喜歡在應(yīng)用程序中實現(xiàn),而不是在數(shù)據(jù)庫上實現(xiàn)。
Oracle認(rèn)證全面解析
Oracle是第一個跨整個產(chǎn)品線(數(shù)據(jù)庫、業(yè)務(wù)應(yīng)用軟件和應(yīng)用軟件開發(fā)與決策支持工具)開發(fā)和部署100%基于互聯(lián)網(wǎng)的企業(yè)軟件的公司。下面是我整理的關(guān)于Oracle認(rèn)證管理員認(rèn)證考試,希望大家認(rèn)真閱讀!
一、 Oracle,僅次于微軟的世界第二大軟件公司
Oracle雖然規(guī)模很大,但名聲不像微軟、IBM那樣顯赫,很多非計算機專業(yè)的在校學(xué)生不知道Oracle是何物。但是如果你是一位想在畢業(yè)后進入IT行業(yè)的學(xué)生,那么,你必須知道什么是Oracle.
首先,Oracle是一家軟件公司。這家1977成立于加利福尼亞的軟件公司是世界上第一個推出關(guān)系型數(shù)據(jù)管理系統(tǒng)(RDBMS)的公司?,F(xiàn)在,他們的RDBMS被廣泛應(yīng)用于各種操作環(huán)境:Windows NT、基于UNIX系統(tǒng)的小型機、IBM大型機以及一些專用硬件操作系統(tǒng)平臺。事實上,Oracle已經(jīng)成為世界上最大的RDBMS供應(yīng)商,并且是世界上最主要的信息處理軟件供應(yīng)商?,F(xiàn)在,Oracle是僅次于微軟公司的世界第二大軟件公司,2000年的銷售額為101億美元?,F(xiàn)在Oracle在世界范圍內(nèi)大約聘用了4萬3千多名專業(yè)技術(shù)人員,在美國本土有2萬1千名。有趣的是,即使在美國本土,Oracle的技術(shù)人員(主要是程序員)中有40%是印度人,中國人是第二多的,其次才是美國人。
然后,Oracle是一個龐大的品牌系統(tǒng)。如前所述,Oracle不僅在全球最先推出了RDBMS,并且事實上掌握著這個市場的大部分份額,由于Oracle 公司的RDBMS都以O(shè)racle為名,所以,在某種程度上Oracle己經(jīng)成為了RDBMS的代名詞。而近幾年來,Oracle不斷積極地擴展自己的業(yè)務(wù),成功地開發(fā)了許多橫向和縱向的產(chǎn)品,譬如Oracle自己設(shè)計生產(chǎn)的Oracle服務(wù)器,面對商業(yè)客戶的商業(yè)交易系統(tǒng)(Oracle Exchange),Oracle數(shù)據(jù)中心等等。同時,Oracle還成功開發(fā)出了很多面對程序員的開發(fā)工具,譬如著名的Designer/2000計算機輔助系統(tǒng)工程(CASE)工具和Developer/2000開發(fā)包,這些工具作為“設(shè)計器”和“開發(fā)器”,有力地幫助了程序員的開發(fā)工作,也有力地提高了Oracle的聲譽。此外,Oracle還開發(fā)了一系列面對不同對象的應(yīng)用軟件,它們被統(tǒng)稱為Oracle應(yīng)用軟件。這些軟件使得Oracle被廣泛應(yīng)用到各個領(lǐng)域,同時也為Oracle帶來滾滾財源。比較常見的Oracle軟件產(chǎn)品包括:。Oracle財務(wù)軟件(Oracle Financial)。Oracle制造業(yè)軟件(Oracle Manufacturing)。Oracle人力資源軟件(Oracle Human Resources)。Oracle自動控制軟件(Oracle Automotive)。Oracle 商業(yè)交易系統(tǒng)(Oracle Exchange)
以及其他的應(yīng)用軟件。這些軟件連同OracleRDBMS使得Oracle成為一個龐大的品牌系統(tǒng),深入到了人們生產(chǎn)和生活的各個領(lǐng)域。
由于Oracle擁有多年在各種行業(yè)下的多種解決方案,擁有基于不同客戶環(huán)境的Oracle RDMBS服務(wù)器工具及規(guī)模巨大的應(yīng)用軟件系統(tǒng),而且,這個龐大的系統(tǒng)正在不同程度、不同層次地為各行各業(yè)所廣泛應(yīng)用。因此,能夠熟練掌握這個系統(tǒng)的某些方面及適應(yīng)這個系統(tǒng)的不斷更新的專業(yè)工程師必然是各界急需的人才,有著良好的就業(yè)前景。事實上,Oracle公司也認(rèn)識到了這一點,這就是Oracle認(rèn)證專家——OCP(Oracle Certified Professional)的由來。
二、Oracle認(rèn)證種類介紹
Oracle認(rèn)證專家——OCP,是由Oracle公司授權(quán)國際考試認(rèn)證中心對考生進行的資格認(rèn)證??忌纯荚嚇?biāo)準(zhǔn)要求參加幾門課程的.考試(一般為3—5門),在通過全部考試后,便可獲得OCP的專家認(rèn)證。
目前OCP認(rèn)證考試分為:
Database Administrator:數(shù)據(jù)庫管理員考試認(rèn)證,簡稱DBA.數(shù)據(jù)庫管理員負(fù)責(zé)對數(shù)據(jù)庫進行日常的管理、備份及數(shù)據(jù)庫崩潰后的恢復(fù)問題。
Database Operator:數(shù)據(jù)庫操作員認(rèn)證考試,簡稱DBO.數(shù)據(jù)庫操作員主要是基于Windows NT的Oracle 8數(shù)據(jù)庫管理,能夠熟練應(yīng)用OEM等工具完成對數(shù)據(jù)庫的操作及日常的管理工作。
Database Developer:數(shù)據(jù)庫開發(fā)員認(rèn)證考試,簡稱DEV.數(shù)據(jù)庫開發(fā)員應(yīng)能熟練掌握用Developer/2000的工具建立各種Forms應(yīng)用程序,建立各種標(biāo)準(zhǔn)的以及自定義的報表。
Java Developer:Java開發(fā)人員考試。
Application Consultant: Oracle產(chǎn)品應(yīng)用咨詢顧問。
其中,Oracle DBA是最吃香,但也是最難考的一個認(rèn)證。在Oracle的官方的網(wǎng)站上,對DBA有以下說明:
Oracle DBA專家可以跟上如今日趨復(fù)雜的系統(tǒng)環(huán)境要求。最好的DBA們都在幕后工作,他們小心地維護著系統(tǒng),使得系統(tǒng)可以每天都平穩(wěn)地運轉(zhuǎn),并且防止意外災(zāi)難的發(fā)生,譬如數(shù)據(jù)庫崩潰或者成小時地宕機。這項艱巨的任務(wù)需要對Oracle數(shù)據(jù)庫的結(jié)構(gòu)和運行方式有著廣泛泛深入的了解,并且有豐富的實戰(zhàn)經(jīng)驗。最好的DBA可以在取得最佳運行狀態(tài)及防止他們公司停止運行的突發(fā)事件中找到平衡。Oracle DBA認(rèn)證考試就是提供一個證明該人可以勝任Oracle DBA這一職務(wù)的認(rèn)證。本認(rèn)證考試設(shè)計了5門獨立的考試,使你可以利用良好的知識獲得一個專家認(rèn)證。
三、如何參加考試?
OCP認(rèn)證的所有考試也是通過Prometric公司組織的,具體的考試事宜請訪問它的官方的網(wǎng)站:
目前OCP每門考試的費用為125美元。
四、如何準(zhǔn)備考試?
1、Oracle公司推薦的官方準(zhǔn)備途徑
一般來講,Oracle的考試內(nèi)容比較多,并且考題也很細(xì),對動手能力要求很強。因此,為了有足夠的把握,一定要提前充分準(zhǔn)備,而且一定要注重動手實踐。在Oracle官方的網(wǎng)站上推薦的通過認(rèn)證的途徑如下,可以進行參考。
Oracle大學(xué):Oracle大學(xué)提供的教師引導(dǎo)及基于技術(shù)的訓(xùn)練(Instructor-led training and technology- based training)是準(zhǔn)備OCP認(rèn)證的最好方式,這些課程將為你打下需要通過OCP認(rèn)證的知識基礎(chǔ)。你可以查閱一下課程表來選擇理想的準(zhǔn)備方式,你當(dāng)?shù)氐腛racle大學(xué)可以在這方面給你一些最好的建議。你可以訪問Oracle的網(wǎng)站,獲得更多的信息。
自己準(zhǔn)備:實戰(zhàn)經(jīng)驗是加深你對Oracle考試內(nèi)容理解的最好方式。Oracle建議你將理論學(xué)習(xí)拓展,在實際工作或是練習(xí)中使用新學(xué)到的技巧和知識來自學(xué)。
考試內(nèi)容檢查表:使用考試內(nèi)容檢查表(Test Content Checklist)來確定你必須準(zhǔn)備的所有題目。Oracle會不斷地更新考試內(nèi)容檢查表,所以請訪問Oracle網(wǎng)站 ,下載最新的考試指南。
其它考試工具:模擬考試題及自我測試軟件可以幫助你更好地準(zhǔn)備OCP認(rèn)證考試。Oracle和自我測試軟件公司(Self Test Software)聯(lián)合出品了一些高質(zhì)量的考試軟件以幫助考生更好地準(zhǔn)備OCP認(rèn)證考試,這些軟件可以通過 Oracle 網(wǎng)站 定購。
事實上,絕大部分的大陸同學(xué)都是通過參加培訓(xùn)班來準(zhǔn)備考試的,它們不僅輔導(dǎo)通過考試的知識,而且其他信息包括如何報名,考場上如何應(yīng)考,都可以得到輔導(dǎo)。以上Oracle官方的介紹只是一般地對你進行一下有關(guān)備考的初級教育,事實上,正像我們前面說過的,作為一個龐大的數(shù)據(jù)庫系統(tǒng),要想掌握好Oracle(更不要說完全掌握了——我甚至懷疑是否有人真正完全掌握過Oracle),從任何角度而言都不是一件易事。除非你有足夠的決心和耐心,準(zhǔn)備將Oracle當(dāng)作你的職業(yè)之路并致力于數(shù)據(jù)庫技術(shù)的研究,你才有可能真正了解這個龐雜系統(tǒng)的精髓。以下的一些論述將有助于你對Oracle有一個初步的了解。
2、Oracle數(shù)據(jù)庫技術(shù)基本知識
(1)Oracle數(shù)據(jù)庫涵蓋了數(shù)據(jù)庫技術(shù)的方方面面。
盡管關(guān)系型數(shù)據(jù)庫從原理上來講并不是很難,有一些數(shù)據(jù)庫知識的人掌握這些原理并不會花很大的氣力,而且,一般的關(guān)系型數(shù)據(jù)庫軟件,譬如 SQL Server,用起來并不復(fù)雜,但Oracle絕對與眾不同。作為有史以來最成功的關(guān)系型數(shù)據(jù)庫軟件,Oracle的實現(xiàn)方式和管理維護手段非常豐富,它涉及到很多方面的細(xì)節(jié)技術(shù)。單從任何一個側(cè)面來理解它,是難觀其全貌的。要想真的精通它,沒有兩三年功夫是不行的。單是Oracle的技術(shù)文檔,就足夠淹沒你的! 具體說來,Oracle技術(shù)包括以下幾個主要方面:Oracle系統(tǒng)結(jié)構(gòu)和原理、Oracle數(shù)據(jù)庫的安裝和配置、Oracle數(shù)據(jù)庫的管理、Oracle的數(shù)據(jù)備份與恢復(fù)技術(shù)、Oracle的性能調(diào)整、Oracle的新產(chǎn)品特性(Java支持、應(yīng)用服務(wù)器、時間空間系列、文本服務(wù)等)、Oracle的并行服務(wù)器技術(shù)、Oracle的數(shù)據(jù)倉庫技術(shù)、Oracle的對象類型和對象一關(guān)系模型等技術(shù)……
毫不夸張地說,以上任何一個部分單獨拿出來都是很大的題目!
(2)Oracle技術(shù)發(fā)展快,技術(shù)的關(guān)聯(lián)性大。
盡管Oracle只是一個數(shù)據(jù)庫系統(tǒng),但在實際應(yīng)用中,你不可能只面對數(shù)據(jù)庫本身。譬如,你在做Oracle數(shù)據(jù)庫的網(wǎng)絡(luò)管理,你將不可避免地遇到如何與網(wǎng)絡(luò)通訊、防火墻的技術(shù)兼容的問題。同理,你在做其它方面的工作,也肯定有方方面面的技術(shù)關(guān)聯(lián)問題需要解決。而且更要命的是,這些技術(shù)(包括Oracle本身)發(fā)展速度都非???,這就使得跟上它們的發(fā)展成為一件十分費勁的事情。
不過幸運的是,我們并不需要同時了解Oracle的所有方面,Oracle提供了很多應(yīng)用方向,我們可以按照偏好,選擇其中的一個方向,集中時間和精力,努力在這個方向做到有所成就還不是一件很難的事情。由于Oracle目前已是世界上最主要的數(shù)據(jù)庫供應(yīng)商和第二大軟件公司,Oracle的數(shù)據(jù)庫技術(shù)已經(jīng)被廣泛應(yīng)用于各個領(lǐng)域,因而市場上對Oracle人才的需求量是相當(dāng)之大,獲得OCP認(rèn)證不愁找不到工作。而以后我們可以在工作中學(xué)以致用,再努力地鉆研Oracle數(shù)據(jù)庫及相關(guān)技術(shù)。
;
1. 預(yù)估執(zhí)行計劃 - Explain Plan
Explain plan以SQL語句作為輸入,得到這條SQL語句的執(zhí)行計劃,并將執(zhí)行計劃輸出存儲到計劃表中。
首先,在你要執(zhí)行的SQL語句前加explain plan for,此時將生成的執(zhí)行計劃存儲到計劃表中,語句如下:
explain plan for SQL語句
然后,在計劃表中查詢剛剛生成的執(zhí)行計劃,語句如下:
select * from table(dbms_xplan.display);
注意:Explain plan只生成執(zhí)行計劃,并不會真正執(zhí)行SQL語句,因此產(chǎn)生的執(zhí)行計劃有可能不準(zhǔn),因為:
1)當(dāng)前的環(huán)境可能和執(zhí)行計劃生成時的環(huán)境不同;
2)不會考慮綁定變量的數(shù)據(jù)類型;
3)不進行變量窺視。
2. 查詢內(nèi)存中緩存的執(zhí)行計劃 (dbms_xplan.display_cursor)
如果你想獲取正在執(zhí)行的或剛執(zhí)行結(jié)束的SQL語句真實的執(zhí)行計劃(即獲取library cache中的執(zhí)行計劃),可以到動態(tài)性能視圖里查詢。方法如下:
1)獲取SQL語句的游標(biāo)
游標(biāo)分為父游標(biāo)和子游標(biāo),父游標(biāo)由sql_id(或聯(lián)合address和hash_value)字段表示,子游標(biāo)由child_number字段表示。
如果SQL語句正在運行,可以從v$session中獲得它的游標(biāo)信息,如:
select status, sql_id, sql_child_number from v$session where status='ACTIVE' and ....
如果知道SQL語句包含某些關(guān)鍵字,可以從v$sql視圖中獲得它的游標(biāo)信息,如:
select sql_id, child_number, sql_text from v$sql where sql_text like '%關(guān)鍵字%‘
2)獲取庫緩存中的執(zhí)行計劃
為了獲取緩存庫中的執(zhí)行計劃,可以直接查詢動態(tài)性能視圖v$sql_plan和v$sql_plan_statistics_all等,但更方便的方法是以sql_id和子游標(biāo)為參數(shù),執(zhí)行如下語句:
select * from table(dbms_xplan.display_cursor('sql_id',child_number));
3)獲取前一次的執(zhí)行計劃:
set serveroutput off
select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
3. 查詢歷史執(zhí)行計劃(dbms_xplan.display_awr)
AWR會定時把動態(tài)性能視圖中的執(zhí)行計劃保存到dba_hist_sql_plan視圖中,如果你想要查看歷史執(zhí)行計劃,可以采用如下方法查詢:
select * from table(dbms_xplan.display_awr('sql_id');
4. 在用sqlplus做SQL開發(fā)是(Autotrace)
set autotrace是sqlplus工具的一個功能,只能在通過sqlplus連接的session中使用,它非常適合在開發(fā)時測試SQL語句的性能,有以下幾種參數(shù)可供選擇:
SET AUTOTRACE OFF ---------------- 不顯示執(zhí)行計劃和統(tǒng)計信息,這是缺省模式
SET AUTOTRACE ON EXPLAIN ------ 只顯示優(yōu)化器執(zhí)行計劃
SET AUTOTRACE ON STATISTICS -- 只顯示統(tǒng)計信息
SET AUTOTRACE ON ----------------- 執(zhí)行計劃和統(tǒng)計信息同時顯示
SET AUTOTRACE TRACEONLY ------ 不真正執(zhí)行,只顯示預(yù)期的執(zhí)行計劃,同explain plan
5. 生成Trace文件查詢詳細(xì)的執(zhí)行計劃 (SQL_Trace, 10046)
SQL_TRACE作為初始化參數(shù)可以在實例級別啟用,也可以只在會話級別啟用,在實例級別啟用SQL_TRACE會導(dǎo)致所有進程的活動被跟蹤,包括后臺進程及所有用戶進程,這通常會導(dǎo)致比較嚴(yán)重的性能問題,所以在一般情況下,我們使用sql_trace跟蹤當(dāng)前進程,方法如下:
SQLalter session set sql_trace=true;
...被跟蹤的SQL語句...
SQLalter session set sql_trace=false;
如果要跟蹤其它進程,可以通過Oracle提供的系統(tǒng)包DBMS_SYSTEM. SET_SQL_TRACE_IN_SESSION來實現(xiàn),例如:
SQL exec dbms_system.set_sql_trace_in_session(sid,serial#,true) --開始跟蹤
SQL exec dbms_system.set_sql_trace_in_session(sid,serial#,false) --結(jié)束跟蹤
生成trace文件后,再用tkprof 工具將sql trace 生成的跟蹤文件轉(zhuǎn)換成易讀的格式,語法如下:
tkprof inputfile outputfile
10046事件是SQL_TRACE的一個升級版,它也是追蹤會話,生成Trace文件,只是它里面的內(nèi)容更詳細(xì)
以oracle表分析為例:
drop table test;
select count(*) from test;
--創(chuàng)建測試表
create table test
(
id number(9),
nick varchar2(30)
);
--插入測試數(shù)據(jù)
begin
for i in 1..100000 loop
insert into test(id) values(i);
end loop;
commit;
end;
select * from test;
--更新nick字段,使數(shù)據(jù)發(fā)生嚴(yán)重傾斜
update test set nick='abc' where rownum99999;
--創(chuàng)建索引
create index idx_test_nick on test(nick);
update test set nick='def' where nick is null;
--只對索引進行分析
analyze index idx_test_nick compute statistics;
select * from user_indexes;
--查看索引名,對應(yīng)存儲的數(shù)據(jù)塊,不同的key數(shù)量,記錄數(shù)(行數(shù))的分析信息
select index_name, LEAF_BLOCKS, DISTINCT_KEYS, NUM_ROWS
from user_indexes
where index_name = 'IDX_TEST_NICK';
--dba_tab_col_statistics
--查看表的統(tǒng)計信息
select COLUMN_NAME, NUM_BUCKETS, num_distinct
from USER_tab_columns
where table_name = 'TEST';
select * from test where nick ='abc';
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST'
2 1 INDEX (RANGE SCAN) OF 'IDX_TEST_NICK' (NON-UNIQUE)
select * from test where nick ='def';
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST'
2 1 INDEX (RANGE SCAN) OF 'IDX_TEST_NICK' (NON-UNIQUE)
--由上可以看到,對索引分析之后,sql的執(zhí)行路徑都是基于規(guī)則的,索引的字段的偏移
--先根據(jù)索引找到rowid,然后再根據(jù)rowid讀取記錄,這個過程肯定比全表掃描讀取記錄要慢
--user_part_col_statistics 分區(qū)分析信息
--分析表的第二列nick
analyze table test compute statistics for columns size 2 nick;
select * from test where nick ='abc';
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST'
2 1 INDEX (RANGE SCAN) OF 'IDX_TEST_NICK' (NON-UNIQUE)
--根據(jù)上面的執(zhí)行計劃,還是按照規(guī)則來執(zhí)行的
--分析表
analyze table test compute statistics for table;
select * from test where nick ='abc';
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=49 Card=99998 Bytes=
1499970)
1 0 TABLE ACCESS (FULL) OF 'TEST' (Cost=49 Card=99998 Bytes=14
99970)
--分析表之后,完全按照成本來執(zhí)行
--刪除所有的統(tǒng)計數(shù)據(jù),并只對表與列進行分析,不分析索引,
--ORACLE使用CBO的優(yōu)化器,并產(chǎn)生了正確的執(zhí)行計劃
analyze table test delete statistics;
--分析列nick
analyze table test compute statistics for table for columns size 2 nick;
select * from test where nick ='abc';
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=49 Card=99998 Bytes=
1499970)
1 0 TABLE ACCESS (FULL) OF 'TEST' (Cost=49 Card=99998 Bytes=14
99970)
--
select * from test where nick ='def';
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=2 Bytes=30)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST' (Cost=2 Card=2 Byt
es=30)
2 1 INDEX (RANGE SCAN) OF 'IDX_TEST_NICK' (NON-UNIQUE) (Cost
=1 Card=2)
--創(chuàng)建TEST表ID列上的索引,但不對索引進行分析
create index idx_test_id on test(id);
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1000 Bytes=15
000)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST' (Cost=2 Card=1000
Bytes=15000)
2 1 INDEX (RANGE SCAN) OF 'IDX_TEST_ID' (NON-UNIQUE) (Cost=1
Card=400)
--當(dāng)條件中即有id,又有nick時,因為nick上有直方圖,ORACLE知道nick='abc'的值特別的多,所以不走IDX_TEST_NICK索引,走IDX_TEST_ID上的索引
select * from test where id=5 and nick='abc';
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1000 Bytes=15
000)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST' (Cost=2 Card=1000
Bytes=15000)
2 1 INDEX (RANGE SCAN) OF 'IDX_TEST_ID' (NON-UNIQUE) (Cost=1
Card=400)
--當(dāng)條件中即有id,又有nick時,因為nick上有直方圖,ORACLE知道nick='def'的值特別的少,所以走IDX_TEST_NICK上的索引,不走IDX_TEST_ID索引
select * from test where id=5 and nick='def';
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=15)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST' (Cost=2 Card=1 Byt
es=15)
2 1 INDEX (RANGE SCAN) OF 'IDX_TEST_NICK' (NON-UNIQUE) (Cost
=1 Card=2)
select * from test where nick='def' and id=5;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=15)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST' (Cost=2 Card=1 Byt
es=15)
2 1 INDEX (RANGE SCAN) OF 'IDX_TEST_NICK' (NON-UNIQUE) (Cost
=1 Card=2)
--在分析ID列后,ORACLE發(fā)現(xiàn)ID列的選擇度更高,所以不再選擇IDX_TEST_NICK索引,而是選擇IDX_TEST_ID
analyze table test compute statistics for columns size 1 id;
select * from test where id=5 and nick='def';
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=7)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST' (Cost=2 Card=1 Byt
es=7)
2 1 INDEX (RANGE SCAN) OF 'IDX_TEST_ID' (NON-UNIQUE) (Cost=1
Card=1)
/*
下面來看另外一種情況,我們刪除所有的統(tǒng)計數(shù)據(jù),然后在ID列上創(chuàng)建唯一索引,在此條件下,
只分析表與分析列nick,我們看到ORACLE走了正確的執(zhí)行計劃,
走了UK_TEST_ID,其實從這里也給我們帶來很多的啟示:
在主鍵與唯一鍵約束的列上是否需要直方圖的問題?
如果在這些列上有像這樣的查詢where id 100 and id 1000,
我們還是需要有直方圖的,但除此之外,好像真的沒有直方圖的必要了!
*/
analyze table test delete statistics;
drop index idx_test_id;
create unique index uk_test_id on test(id);
--分析表的第二列nick
analyze table test compute statistics for table for columns size 2 nick;
select * from test where id=5 and nick='def';
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=15)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST' (Cost=2 Card=1 Byt
es=15)
2 1 INDEX (UNIQUE SCAN) OF 'UK_TEST_ID' (UNIQUE) (Cost=1 Car
d=100000)
從以上一系列的實驗可以看出,對ORACLE的優(yōu)化器CBO來說,表的分析與列的分析才是最重要的,索引的分析次之。還有我們可以考慮我們的哪些列上需要直方圖,對于bucket的個數(shù)問題,oracle的默認(rèn)值是75個,所以根據(jù)你的應(yīng)用規(guī)則,選擇合適的桶數(shù)對性能也是有幫助的。因為不必要的桶的個數(shù)的大量增加,必然會帶來SQL語句硬解析時產(chǎn)生執(zhí)行計劃的復(fù)雜度問題。
實現(xiàn)思路:可以通過w3c的dom解析器進行操作,之后通過getName獲取到xmltpye中的屬性值。
舉例:
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public class DomTest1
{
public static void main(String[] args) throws Exception
{
// step 1: 獲得dom解析器工廠(工作的作用是用于創(chuàng)建具體的解析器)
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// System.out.println("class name: " + dbf.getClass().getName());
// step 2:獲得具體的dom解析器
DocumentBuilder db = dbf.newDocumentBuilder();
// System.out.println("class name: " + db.getClass().getName());
// step3: 解析一個xml文檔,獲得Document對象(根結(jié)點)
Document document = db.parse(new File("candidate.xml"));
NodeList list = document.getElementsByTagName("PERSON");
for(int i = 0; i list.getLength(); i++)
{
Element element = (Element)list.item(i);
String content = element.getElementsByTagName("NAME").item(0).getFirstChild().getNodeValue();
System.out.println("name:" + content);
System.out.println("--------------------------------------");
}
}
}