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