理解數據庫服務器執行SQL語句的過程才能更熟悉靈活的操作數據庫
一、SQL語句執行原理
第一步:客戶端與服務器端通信
這里要說明一下客戶端與服務器端的區別,客戶端是為了讓開發者更好的操作,但只是提供了友好的界面,它不執行任何數據的操作,雖然也存在一個數據庫進程但這個進程跟服務器端的進程是一一對應的但還是有區別的。服務器上的數據庫進程才是真正對sql語句進行相關的處理。
第二部:語句解析
當客戶端把 SQL 語句傳送到服務器后,服務器進程會對該語句進行解析。同理,這個解析的工作,也是在服務器端所進行的。下面詳細講解一下服務器解析sql語句的全過程
1. 查詢高速緩存(library cache):數據庫中存在一個高速緩存,當客戶端將SQL語句發送個服務器端是,服務器進程會在數據庫的高速緩存中查找是否存在相同的執行語句。如果存在則直接執行緩存中的已檢驗過的SQL語句。所以,采用高速數據緩存的話,可以提高 SQL 語句的查詢效率。從內存中讀取數據要比從硬盤中的數據文件中讀取數據效率要高。不過這里要注意一點,這個數據緩存跟有些客戶端軟件的數據緩存是兩碼事。有些客戶端軟件為了提高查詢效率,會在應用軟件的客戶端設置數據緩存。由於這些數據緩存的存在,可以提高客戶端應用軟件的查詢效率。但是,若其他人在服務器進行了相關的修改,由於應用軟件數據緩存的存在,導致修改的數據不能及時反映到客戶端上。從這也可以看出,應用軟件的數據緩存跟數據庫服務器的高速數據緩存不是一碼事。
2. 語句合法性檢查(data dict cache)。當在高速緩存中找不到對應的 SQL 語句時,則服務器進程就會開始檢查這條語句的合法性。這里主要是對 SQL 語句的語法進行檢查,看看其是否合乎語法規則。如果服務器進程認為這條 SQL 語句不符合語法規則的時候,就會把這個錯誤信息,反饋給客戶端。在這個語法檢查的過程中,不會對 SQL 語句中所包含的表名、列名等等進行 SQL 他只是語法上的檢查。
3. 語言含義檢查(data dict cache)。若 SQL 語句符合語法上的定義的話,則服務器進程接下去會對語句中的字段、表等內容進行檢查。看看這些字段、表是否在數據庫中。如果表名與列名不准確的話,則數據庫會就會反饋錯誤信息給客戶端。所以,有時候我們寫 select 語句的時候,若語法與表名或者列名同時寫錯的話,則系統是先提示說語法錯誤,等到語法完全正確后,再提示說列名或表名錯誤。
4. 獲得對象解析鎖(control structer)。當語法、語義都正確后,系統就會對我們需要查詢的對象加鎖。這主要是為了保障數據的一致性,防止我們在查詢的過程中,其他用戶對這個對象的結構發生改變。
5. 數據訪問權限的核對(data dict cache)。當語法、語義通過檢查之后,客戶端還不一定能夠取得數據。服務器進程還會檢查,你所連接的用戶是否有這個數據訪問的權限。若你連接上服務器的用戶不具有數據訪問權限的話,則客戶端就不能夠取得這些數據。有時候我們查詢數據的時候,辛辛苦苦地把 SQL 語句寫好、編譯通過,但是,最后系統返回個 “沒有權限訪問數據”的錯誤信息,讓我們氣半死。這在前端應用軟件開發調試的過程中,可能會碰到。所以,要注意這個問題,數據庫服務器進程先檢查語法與語義,然后才會檢查訪問權限。
6. 確定最佳執行計划 ?。當語句與語法都沒有問題,權限也匹配的話,服務器進程還是不會直接對數據庫文件進行查詢。服務器進程會根據一定的規則,對這條語句進行優化。不過要注意,這個優化是有限的。一般在應用軟件開發的過程中,需要對數據庫的 sql 語言進行優化,這個優化的作用要大大地大於服務器進程的自我優化。所以,一般在應用軟件開發的時候,數據庫的優化是少不了的。當服務器進程的優化器確定這條查詢語句的最佳執行計划后,就會將這條 SQL 語句與執行計划保存到數據高速緩存(library cache)。如此的話,等以后還有這個查詢時,就會省略以上的語法、語義與權限檢查的步驟,而直接執行 SQL 語句,提高 SQL 語句處理效率。
第三步:語句執行
語句解析只是對 SQL 語句的語法進行解析,以確保服務器能夠知道這條語句到底表達的是什么意思。等到語句解析完成之后,數據庫服務器進程才會真正的執行這條 SQL 語句。這個語句執行也分兩種情況。一是若被選擇行所在的數據塊已經被讀取到數據緩沖區的話,則服務器進程會直接把這個數據傳遞給客戶端,而不是從數據庫文件中去查詢數據。
若數據不在緩沖區中,則服務器進程將從數據庫文件中查詢相關數據,並把這些數據放入到數據緩沖區中(buffer cache)。
第四步:提取數據
當語句執行完成之后,查詢到的數據還是在服務器進程中,還沒有被傳送到客戶端的用戶進程。所以,在服務器端的進程中,有一個專門負責數據提取的一段代碼。他的作用就是把查詢到的數據結果返回給用戶端進程,從而完成整個查詢動作。從這整個查詢處理過程中,我們在數據庫開發或者應用軟件開發過程中,需要注意以下幾點:一是要了解數據庫緩存跟應用軟件緩存是兩碼事情。數據庫緩存只有在數據庫服務器端才存在,在客戶端是不存在的。只有如此,才能夠保證數據庫緩存中的內容跟數據庫文件的內容一致。才能夠根據
相關的規則,防止數據臟讀、錯讀的發生。而應用軟件所涉及的數據緩存,由於跟數據庫緩存不是一碼事情,所以,應用軟件的數據緩存雖然可以提高數據的查詢效率,但是,卻打破了數據一致性的要求,有時候會發生臟讀、錯讀等情況的發生。所以,有時候,在應用軟件上有專門一個功能,用來在必要的時候清除數據緩存。不過,這個數據緩存的清除,也只是清除本機上的數據緩存,或者說,只是清除這個應用程序的數據緩存,而不會清除數據庫的數據緩存。二是絕大部分 SQL 語句都是按照這個處理過程處理的。我們 DBA 或者基於 Oracle 數據庫的
開發人員了解這些語句的處理過程,對於我們進行涉及到 SQL 語句的開發與調試,是非常有幫助的。有時候,掌握這些處理原則,可以減少我們排錯的時間。特別要注意,數據庫是把數據查詢權限的審查放在語法語義的后面進行檢查的。所以,有時會若光用數據庫的權限控制原則,可能還不能滿足應用軟件權限控制的需要。此時,就需要應用軟件的前台設置,實現權限管理的要求。而且,有時應用數據庫的權限管理,也有點顯得繁瑣,會增加服務器處理的工作量。因此,對於記錄、字段等的查詢權限控制,大部分程序涉及人員喜歡在應用程序中實現,而不是在數據庫上實現
太多文字填幾行代碼把
DBCC DROPCLEANBUFFERS從緩沖池中刪除所有清除緩沖區。
DBCC FREEPROCCACHE從過程緩存中刪除所有元素。
DBCC FREESYSTEMCACHE從所有緩存中釋放所有未使用的緩存條目