SQL語句的執行過程(以oracle爲例)


         在面試中大家經常會被問到關於sql的問題,想流暢的回答要了解一下sql語句的執行過程。以下爲我整理的資料,希望可以幫助大家的學習和工作。



第一步:客戶端把語句發給服務器端執行


當我們在客戶端執行 select 語句時,客戶端會把這條 SQL 語句發送給服務器端,讓服務器端的
進程來處理這語句。也就是說,Oracle 客戶端是不會做任何的操作,他的主要任務就是把客戶端產生
的一些 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
從所有緩存中釋放所有未使用的緩存條目


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章