Select語句能夠說是DBA和數據庫開發者在工做中使用最多的語句之一,但這條語句是如何執行?在Oracle數據庫中又是如何運做的呢?今天咱們就從一條簡單的Select語句開始,看看Oracle數據庫後臺的運做機制。這對於咱們以後的系統管理與故障排除很是有幫助。前端
當咱們在客戶端執行select語句時,客戶端會把這條SQL語句發送給服務器端,讓服務器端的進程來處理這語句。也就是說,Oracle客戶端是不會作任何的操做,他的主要任務就是把客戶端產生的一些SQL語句發送給服務器端。雖然在客戶端也有一個數據庫進程,可是,這個進程的做用跟服務器上的進程做用事不相同的。服務器上的數據庫進程纔會對SQL語句進行相關的處理。不過,有個問題須要說明,就是客戶端的進程跟服務器的進程是一一對應的。也就是說,在客戶端鏈接上服務器後,在客戶端與服務器端都會造成一個進程,客戶端上的咱們叫作客戶端進程;而服務器上的咱們叫作服務器進程。因此,因爲全部的SQL語句都是服務器進程執行的,因此,有些人把服務器進程形象地比喻成客戶端進程的「影子」。sql
當客戶端把SQL語句傳送到服務器後,服務器進程會對該語句進行解析。同理,這個解析的工做,也是在服務器端所進行的。雖然這只是一個解析的動做,可是,其會作不少「小動做」。數據庫
服務器進程在接到客戶端傳送過來的SQL語句時,不會直接去數據庫查詢。而是會先在數據庫的高速緩存中去查找,是否存在相同語句的執行計劃。若是在數據高速緩存中,恰好有其餘人使用這個查詢語句的話,則服務器進程就會直接執行這個SQL語句,省去後續的工做。因此,採用高速數據緩存的話,能夠提升SQL語句的查詢效率。一方面是從內存中讀取數據要比從硬盤中的數據文件中讀取數據效率要高,另外一方面,也是由於這個語句解析的緣由。緩存
不過這裏要注意一點,這個數據緩存跟有些客戶端軟件的數據緩存是兩碼事。有些客戶端軟件爲了提升查詢效率,會在應用軟件的客戶端設置數據緩存。因爲這些數據緩存的存在,能夠提升客戶端應用軟件的查詢效率。可是,若其餘人在服務器進行了相關的修改,因爲應用軟件數據緩存的存在,致使修改的數據不能及時反映到客戶端上。從這也能夠看出,應用軟件的數據緩存跟數據庫服務器的高速數據緩存不是一碼事。服務器
當在高速緩存中找不到對應的SQL語句時,則數據庫服務器進程就會開始檢查這條語句的合法性。這裏主要是對SQL語句的語法進行檢查,看看其是否合乎語法規則。若是服務器進程認爲這條SQL語句不符合語法規則的時候,就會把這個錯誤信息,反饋給客戶端。在這個語法檢查的過程當中,不會對SQL語句中所包含的表名、列名等等進行SQL他只是語法上的檢查。學習
若SQL語句符合語法上的定義的話,則服務器進程接下去會對語句中的字段、表等內容進行檢查。看看這些字段、表是否在數據庫中。若是表名與列名不許確的話,則數據庫會就會反饋錯誤信息給客戶端。優化
因此,有時候咱們寫select語句的時候,若語法與表名或者列名同時寫錯的話,則系統是先提示說語法錯誤,等到語法徹底正確後,再提示說列名或表名錯誤。若可以掌握這個順序的話,則在應用程序排錯的時候,能夠節省時間。spa
當語法、語義都正確後,系統就會對咱們須要查詢的對象加鎖。這主要是爲了保障數據的一致性,防止咱們在查詢的過程當中,其餘用戶對這個對象的結構發生改變。對於加鎖的原理與方法,我在其餘文章中已經有專門敘述,在這裏就略過不談了。調試
當語法、語義經過檢查以後,客戶端還不必定可以取得數據。服務器進程還會檢查,你所鏈接的用戶是否有這個數據訪問的權限。若你鏈接上服務器的用戶不具備數據訪問權限的話,則客戶端就不可以取得這些數據。故,有時候咱們查詢數據的時候,辛辛苦苦地把SQL語句寫好、編譯經過,可是,最後系統返回個「沒有權限訪問數據」的錯誤信息,讓咱們氣半死。這在前端應用軟件開發調試的過程當中,可能會碰到。因此,要注意這個問題,數據庫服務器進程先檢查語法與語義,而後纔會檢查訪問權限。對象
當語句與語法都沒有問題,權限也匹配的話,服務器進程仍是不會直接對數據庫文件進行查詢。服務器進程會根據必定的規則,對這條語句進行優化。不過要注意,這個優化是有限的。通常在應用軟件開發的過程當中,須要對數據庫的sql語言進行優化,這個優化的做用要大大地大於服務器進程的自我優化。因此,通常在應用軟件開發的時候,數據庫的優化是少不了的。
當服務器進程的優化器肯定這條查詢語句的最佳執行計劃後,就會將這條SQL語句與執行計劃保存到數據高速緩存。如此的話,等之後還有這個查詢時,就會省略以上的語法、語義與權限檢查的步驟,而直接執行SQL語句,提升SQL語句處理效率。
語句解析只是對SQL語句的語法進行解析,以確保服務器可以知道這條語句到底表達的是什麼意思。等到語句解析完成以後,數據庫服務器進程纔會真正的執行這條SQL語句。
這個語句執行也分兩種狀況。一是若被選擇行所在的數據塊已經被讀取到數據緩衝區的話,則服務器進程會直接把這個數據傳遞給客戶端,而不是從數據庫文件中去查詢數據。若數據不在緩衝區中,則服務器進程將從數據庫文件中查詢相關數據,並把這些數據放入到數據緩衝區中。
這裏仍然要注意一點,就是Oracle數據庫中,定義了不少種類的高速緩存。像上面所說的SQL語句緩存與如今講的數據緩存。咱們在學習數據庫的時候,須要對這些緩存有一個清晰的認識,並瞭解各個種類緩存的做用。這對於咱們後續數據庫維護與數據庫優化是很是有用的。
第四步:提取數據。
當語句執行完成以後,查詢到的數據仍是在服務器進程中,尚未被傳送到客戶端的用戶進程。因此,在服務器端的進程中,有一個專門負責數據提取的一段代碼。他的做用就是把查詢到的數據結果返回給用戶端進程,從而完成整個查詢動做。
從這整個查詢處理過程當中,咱們在數據庫開發或者應用軟件開發過程當中,須要注意如下幾點:
一是要了解數據庫緩存跟應用軟件緩存是兩碼事情。數據庫緩存只有在數據庫服務器端才存在,在客戶端是不存在的。只有如此,纔可以保證數據庫緩存中的內容跟數據庫文件的內容一致。纔可以根據相關的規則,防止數據髒讀、錯讀的發生。而應用軟件所涉及的數據緩存,因爲跟數據庫緩存不是一碼事情,因此,應用軟件的數據緩存雖然能夠提升數據的查詢效率,可是,卻打破了數據一致性的要求,有時候會發生髒讀、錯讀等狀況的發生。因此,有時候,在應用軟件上有專門一個功能,用來在必要的時候清除數據緩存。不過,這個數據緩存的清除,也只是清除本機上的數據緩存,或者說,只是清除這個應用程序的數據緩存,而不會清除數據庫的數據緩存。
二是絕大部分SQL語句都是按照這個處理過程處理的。咱們DBA或者基於Oracle數據庫的開發人員瞭解這些語句的處理過程,對於咱們進行涉及到SQL語句的開發與調試,是很是有幫助的。有時候,掌握這些處理原則,能夠減小咱們排錯的時間。特別要注意,數據庫是把數據查詢權限的審查放在語法語義的後面進行檢查的。因此,有時會若光用數據庫的權限控制原則,可能還不能知足應用軟件權限控制的須要。此時,就須要應用軟件的前臺設置,實現權限管理的要求。並且,有時應用數據庫的權限管理,也有點顯得繁瑣,會增長服務器處理的工做量。所以,對於記錄、字段等的查詢權限控制,大部分程序涉及人員喜歡在應用程序中實現,而不是在數據庫上實現。