假如,我們現在利用Select語句從資料庫查詢資料,Oracle資料庫是如何運作的呢?從中我們可以領悟到什麼呢?下面,就結合一條簡單的select語句,看看Oracle資料庫背景運作機制。這對於我們之後的系統管理與故障排除非常有協助。
第一步:用戶端把語句發給伺服器端執行。
當我們在用戶端執行select語句時,用戶端會把這條SQL語句發送給伺服器端,讓伺服器端的進程來處理這語句。也就是說,Oracle用戶端是不會做任何的操作,他的主要任務就是把用戶端產生的一些SQL語句發送給伺服器端。雖然在用戶端也有一個資料庫進程,但是,這個進程的作用跟伺服器上的進程作用事不相同的。伺服器上的資料庫進程才會對SQL語句進行相關的處理。不過,有個問題需要說明,就是用戶端的進程跟伺服器的進程是一一對應的。也就是說,在用戶端串連上伺服器後,在用戶端與伺服器端都會形成一個進程,用戶端上的我們叫做用戶端進程;而伺服器上的我們叫做伺服器處理序。所以,由於所有的SQL語句都是伺服器處理序執行的,所以,有些人把伺服器處理序形象地比喻成用戶端進程的“影子”。
第二步:語句解析。
當用戶端把SQL語句傳送到伺服器後,伺服器處理序會對該語句進行解析。同理,這個解析的工作,也是在伺服器端所進行的。雖然這隻是一個解析的動作,但是,其會做很多“小動作”。
1、查詢快取。伺服器處理序在接到用戶端傳送過來的SQL語句時,不會直接去資料庫查詢。而是會先在資料庫的快取中去尋找,是否存在相同語句的執行計畫。如果在資料快取中,剛好有其他人使用這個查詢語句的話,則伺服器處理序就會直接執行這個SQL語句,省去後續的工作。所以,採用高速資料緩衝的話,可以提高SQL語句的查詢效率。一方面是從記憶體中讀取資料要比從硬碟中的資料檔案中讀取資料效率要高,另一方面,也是因為這個語句解析的原因。
不過這裡要注意一點,這個資料緩衝跟有些用戶端軟體的資料緩衝是兩碼事。有些用戶端軟體為了提高查詢效率,會在應用軟體的用戶端設定資料緩衝。由於這些資料緩衝的存在,可以提高用戶端應用軟體的查詢效率。但是,若其他人在伺服器進行了相關的修改,由於應用軟體資料緩衝的存在,導致修改的資料不能及時反映到用戶端上。從這也可以看出,應用軟體的資料緩衝跟資料庫伺服器的高速資料緩衝不是一碼事。
2、語句合法性檢查。
當在快取中找不到對應的SQL語句時,則資料庫伺服器進程就會開始檢查這條語句的合法性。這裡主要是對SQL語句的文法進行檢查,看看其是否合乎文法規則。如果伺服器處理序認為這條SQL語句不符合文法規則的時候,就會把這個錯誤資訊,反饋給用戶端。在這個語法檢查的過程中,不會對SQL語句中所包含的表名、列名等等進行SQL他只是文法上的檢查。
3、語言含義檢查。
若SQL語句符合文法上的定義的話,則伺服器處理序接下去會對語句中的欄位、表等內容進行檢查。看看這些欄位、表是否在資料庫中。如果表名與列名不準確的話,則資料庫會就會反饋錯誤資訊給用戶端。
所以,有時候我們寫select語句的時候,若文法與表名或者列名同時寫錯的話,則系統是先提示說語法錯誤,等到文法完全正確後,再提示說列名或表名錯誤。若能夠掌握這個順序的話,則在應用程式排錯的時候,可以節省時間。
4、獲得對象解析鎖。
當文法、語義都正確後,系統就會對我們需要查詢的對象加鎖。這主要是為了保障資料的一致性,防止我們在查詢的過程中,其他使用者對這個對象的結構發生改變。對於加鎖的原理與方法,我在其他文章中已經有專門敘述,在這裡就略過不談了。
5、資料存取權限的核對。
當文法、語義通過檢查之後,用戶端還不一定能夠取得資料。伺服器處理序還會檢查,你所串連的使用者是否有這個資料訪問的許可權。若你串連上伺服器的使用者不具有資料存取權限的話,則用戶端就不能夠取得這些資料。故,有時候我們查詢資料的時候,辛辛苦苦地把SQL語句寫好、編譯通過,但是,最後系統返回個“沒有許可權訪問資料”的錯誤資訊,讓我們氣半死。這在前端應用軟體開發調試的過程中,可能會碰到。所以,要注意這個問題,資料庫伺服器進程先檢查文法與語義,然後才會檢查存取權限。
6、確定最佳執行計畫。
當語句與文法都沒有問題,許可權也匹配的話,伺服器處理序還是不會直接對資料庫檔案進行查詢。伺服器處理序會根據一定的規則,對這條語句進行最佳化。不過要注意,這個最佳化是有限的。一般在應用軟體開發的過程中,需要對資料庫的sql語言進行最佳化,這個最佳化的作用要大大地大於伺服器處理序的自我最佳化。所以,一般在應用軟體開發的時候,資料庫的最佳化是少不了的。
當伺服器處理序的最佳化器確定這條查詢語句的最佳執行計畫後,就會將這條SQL語句與執行計畫儲存到資料快取。如此的話,等以後還有這個查詢時,就會省略以上的文法、語義與許可權檢查的步驟,而直接執行SQL語句,提高SQL語句處理效率。
第三步:語句執行。
語句解析只是對SQL語句的文法進行解析,以確保伺服器能夠知道這條語句到底表達的是什麼意思。等到語句解析完成之後,資料庫伺服器進程才會真正的執行這條SQL語句。
這個語句執行也分兩種情況。一是若被選擇行所在的資料區塊已經被讀取到資料緩衝區的話,則伺服器處理序會直接把這個資料傳遞給用戶端,而不是從資料庫檔案中去查詢資料。若資料不在緩衝區中,則伺服器處理序將從資料庫檔案中查詢相關資料,並把這些資料放入到資料緩衝區中。
這裡仍然要注意一點,就是Oracle資料庫中,定義了很多種類的快取。像上面所說的SQL語句緩衝與現在講的資料緩衝。我們在學習資料庫的時候,需要對這些緩衝有一個清晰的認識,並瞭解各個種類緩衝的作用。這對於我們後續資料庫維護與資料庫最佳化是非常有用的。
第四步:提取資料。
當語句執行完成之後,查詢到的資料還是在伺服器處理序中,還沒有被傳送到用戶端的使用者進程。所以,在伺服器端的進程中,有一個專門負責資料提取的一段代碼。他的作用就是把查詢到的資料結果返回給使用者端進程,從而完成整個查詢動作。
從這整個查詢處理過程中,我們在資料庫開發或者應用軟體開發過程中,需要注意以下幾點:
一是要瞭解資料庫緩衝跟應用軟體緩衝是兩碼事情。資料庫緩衝只有在資料庫伺服器端才存在,在用戶端是不存在的。只有如此,才能夠保證資料庫緩衝中的內容跟資料庫檔案的內容一致。才能夠根據相關的規則,防止資料髒讀、錯讀的發生。而應用軟體所涉及的資料緩衝,由於跟資料庫緩衝不是一碼事情,所以,應用軟體的資料緩衝雖然可以提高資料的查詢效率,但是,卻打破了資料一致性的要求,有時候會發生髒讀、錯讀等情況的發生。所以,有時候,在應用軟體上有專門一個功能,用來在必要的時候清除資料緩衝。不過,這個資料緩衝的清除,也只是清除本機上的資料緩衝,或者說,只是清除這個應用程式的資料緩衝,而不會清除資料庫的資料緩衝。
二是絕大部分SQL語句都是按照這個處理過程處理的。我們DBA或者基於Oracle資料庫的開發人員瞭解這些語句的處理過程,對於我們進行涉及到SQL語句的開發與調試,是非常有協助的。有時候,掌握這些處理原則,可以減少我們排錯的時間。特別要注意,資料庫是把資料查詢許可權的審查放在文法語義的後面進行檢查的。所以,有時會若光用資料庫的許可權控制原則,可能還不能滿足應用軟體許可權控制的需要。此時,就需要應用軟體的前台設定,實現許可權管理的要求。而且,有時應用程式資料庫的許可權管理,也有點顯得繁瑣,會增加伺服器處理的工作量。因此,對於記錄、欄位等的查詢許可權控制,大部分程式涉及人員喜歡在應用程式中實現,而不是在資料庫上實現。
本文出自 “好好活著” 部落格,轉載請與作者聯絡!