【Oracle】一條SQL的一生

一,基礎概念

1,Oracle內存結構

oracle內存結構由兩部分組成SGA(系統全局區)和PGA(用戶全局區)組成
1.1, SGA(System Global Area)系統全局區
這是一個非常龐大的內存區間,也是爲什麼開啓oracle之後佔用了很大內存的原因。這塊區域由所有服務進程和後臺進程共享; SGA分爲不同的池,我們可以通過視圖v$sgastat查看

select pool ,sum(bytes) bytes from v$sgastat group by pool;

SQL執行過程中最主要的pool是
共享緩衝區(shared pool):緩存了各用戶間可共享的各種結構。
數據庫緩衝區緩存(database buffer cache):緩存了從磁盤上檢索的數據塊。
重做日誌緩衝區(redo log buffer):緩存了寫到磁盤之前的重做信息。
SGA詳細內容參考:https://blog.csdn.net/paopaopotter/article/details/79217539

1.2,PGA(Program Global Area) 用戶全局區
當用戶(客戶端)要連接Oracle數據庫時, Oracle就會創建1個session(會話),並且在服務器上創建1個專門處理這個session的進程,就是服務進程。每個服務進程私有的內存區域——PGA,其包含如下結構:
1)Private SQL area:包含綁定信息、運行時的內存結構。每個發出sql語句的會話,都有一個private SQL area(私有SQL區)。
2)Session memory:爲保存會話中的變量以及其他與會話相關的信息,而分配的內存區。

2,Oracle數據庫文件

Oracle數據庫文件主要有以下三類
2.1,數據文件(data files)
每一個Oracle數據庫有一個或多個物理的數據文件(data file),數據文件包含全部數據庫數據,邏輯數據庫結構(如表、索引、視圖、函數)的數據物理地存儲在數據文件中。數據文件中的數據在需要時可以讀取並存儲在數據庫緩衝區緩存中。如用戶要存取數據庫一表的某些數據,如果請求數據不在數據庫緩衝區緩存內,則從相應的數據文件中讀取並存儲在數據庫緩衝區緩存內,當修改或插入新數據時,爲了減少磁盤輸出的總數,提高性能,不必立刻寫入數據文件,修改的數據先存儲在數據庫緩衝區緩存,然後由Oracle後臺進程DBWRn(負責將數據庫緩衝區緩存裏被修改的數據寫入磁盤的數據文件)決定如何將其寫入到相應的數據文件。

2.2,日誌文件(Redo Log Files)
每一個數據庫實例有兩組或以上日誌文件組,爲了防止日誌文件本身的故障,每個日誌文件組可以有一個或以上日誌成員。日誌的主要功能是記錄對數據所作的修改,用於在出現故障時,如果不能將修改數據永久地寫入數據文件,則可利用日誌得到該修改,從而保證數據不丟失。當在數據庫緩衝區緩存修改數據時,會產生一定量的日誌數據,這些日誌數據不會直接就寫到日誌文件中,而是實時存放在重做日誌緩衝區,然後由Oracle後臺進程LGWR(負責將重做日誌緩衝區的內容寫入到磁盤的日誌文件中)決定如何將其寫入到相應的日誌文件。

2.3,控制文件(Control files)
每一Oracle數據庫有一個控制文件(Control File)或同一個控制文件的多個拷貝,它記錄數據庫的物理結構信息,包括數據庫名、數據庫數據文件和日誌文件的名字和位置、數據庫建立日期等。 由於控制文件記錄數據庫的物理結構信息,對數據庫運行至關重要,爲了安全起見,Oracle建議保存兩份以上的控制文件鏡像於不同的存儲設備。

3,物理讀和邏輯讀

所謂邏輯讀,就是從緩存(一般是內存)裏讀取數據,而物理讀,也就是從磁盤(數據文件)裏讀取數據。

二,一條SQL的一生

(一)客戶端發送SQL語句

在這裏插入圖片描述
當我們在客戶端執行SQL語句時,客戶端會把這條SQL語句發送給服務器端,讓服務器端的進程來處理這語句。也就是說,Oracle 客戶端是不會做任何的操作,他的主要任務就是把客戶端產生的一些SQL語句發送給服務器端。服務器進程從用戶進程把信息接收到後, 在PGA 中就要此進程分配所需內存,存儲相關的信息。

(二)SQL語句解析

在這裏插入圖片描述
當客戶端把SQL語句傳送到服務器後,服務器進程會對改語句進行解析。同理,這個解析的工作,也是在服務器端進行的。雖然這只是一個解析的動作,但是,其中包含多個步驟。

1,查詢共享緩衝區中的庫緩存(library cache)
服務器進程在接到客戶端傳送過來的SQL語句時,不會直接去數據庫查詢,服務器進程將到庫緩存中的庫緩存中去查找是否存在相同語句的執行計劃。如果存在,服務器進程將使用這條語句已緩存在共享緩衝區中的庫緩存中的已分析好的執行計劃來執行,省去後續的解析工作,這便是軟解析。若緩存中不存在,則需要進行後面的步驟,這便是硬解析。硬解析通常是昂貴的操作。

2,語句合法性檢查
當在庫緩存中找不到對應的SQL語句時,則服務器進程就會開始檢查這條語句的合法性。這裏主要是對SQL語句的語法進行檢查,看看其是否合乎語法規則。如果服務器進程認爲這條SQL語句不符合語法規則的時候,就會把這個錯誤信息反饋給客戶端。在這個語法檢查的過程中,不會對SQL語句中所包含的表名、列名等等進行檢查,只是檢查語法。

3,語言含義檢查
若SQL 語句符合語法上的定義的話,則服務器進程接下去會對語句中涉及的表、索引、視圖等對象進行解析,並對照數據字典檢查這些對象的名稱以及相關結構,看看這些字段、表、視圖等是否在數據庫中。如果表名與列名不準確的話,則數據庫會就會反饋錯誤信息給客戶端。所以,有時候我們寫select語句的時候,若語法與表名或者列名同時寫錯的話,則系統是先提示說語法錯誤,等到語法完全正確後再提示說列名或表名錯誤。

4,獲得對象解析鎖
當語法、語義都正確後,系統就會對我們需要查詢的對象加鎖。這主要是爲了保障數據的一致性,防止我們在查詢的過程中,其他用戶對這個對象的結構發生改變。

5,數據訪問權限的核對
當語法、語義通過檢查之後,客戶端還不一定能夠取得數據,服務器進程還會檢查連接用戶是否有這個數據訪問的權限。若用戶不具有數據訪問權限的話,則客戶端就不能夠取得這些數據。要注意的是數據庫服務器進程先檢查語法與語義,然後纔會檢查訪問權限。

6,確定最佳執行計劃
當語句與語法都沒有問題,權限也匹配的話,服務器進程還是不會直接對數據庫文件進行查詢。服務器進程會根據一定的規則,對這條語句進行優化。不過要注意,這個優化是有限的。一般在SQL開發的過程中,需要對數據庫的SQL語言進行優化,這個優化的作用優於服務器進程的自我優化。所以,編寫完SQL後需要進行優化。當服務器進程的優化器確定這條查詢語句的最佳執行計劃後,就會將這條SQL語句與執行計劃保存到共享緩衝區的庫緩存。如此的話,等以後還有這個查詢時,就會省略以上的語法、語義與權限檢查的步驟,直接執行SQL語句,提高SQL語句處理效率。

(三)綁定變量賦值

如果SQL語句中使用了綁定變量,掃描綁定變量的聲明,給綁定變量賦值,將變量值帶入執行計劃。

(四)語句執行

語句解析只是對SQL語句的語法進行解析,以確保服務器能夠知道這條語句到底表達的是什麼意思。等到語句解析完成之後,數據庫服務器進程纔會真正的執行這條SQL語句。最常用的就是DML操作,對應的執行過程也有所不同。

1,select操作
在這裏插入圖片描述
1.1,服務器進程先到數據庫緩衝區緩存裏找有沒有現成的數據. 如果有最好, 如果無或者緩存中數據不全的話就只能去訪問數據文件,因爲數據文件存在於物理磁盤中,物理讀寫會耗費IO,降低查詢效率。
1.2,若在緩存中沒找到對應的數據,只能從數據文件獲得數據。
1.3,得到數據後也不是直接發給用客戶端,而是將數據緩存到數據庫緩衝區緩存裏面, 以便當前或其他用戶二次使用。

2,update,insert,delete操作
在這裏插入圖片描述
2.1,檢查所需的數據庫是否已經被讀取到緩衝區緩存中。如果已經存在緩衝區緩存,修改緩存中的數據,同時存放產生的日誌數據到重做日誌緩衝區。
2.2,若所需的數據庫並不在緩衝區緩存中,則服務器將數據塊從數據文件讀取到緩衝區緩存中。
2.3,DBWR:Database writer,後臺進程之一,負責將數據緩衝區緩存裏被修改的數據寫入數據文件。
2.4,LGWR: Log writer,後臺進程之一,負責將重做日誌緩衝區裏的日誌數據寫入到日誌文件。
詳細過程可以看:https://blog.csdn.net/eagle89/article/details/80855584

(五)提取數據

當語句執行完成之後,查詢到的語句還是在服務器進程中,還沒有被傳送到客戶端的用戶進程。所以,在服務器端的進程中,有一個專門負責數據提取的一段代碼。它的作用就是把查詢到的數據結果返回給用戶端進程,從而完成這個查詢動作。

三,參考

https://www.cnblogs.com/augus007/articles/7999586.html
https://www.cnblogs.com/Justsoso-WYH/p/9635846.html
https://blog.csdn.net/eagle89/article/details/80855584
https://blog.csdn.net/paopaopotter/article/details/79217539
https://blog.csdn.net/baidu_36457652/article/details/78816731

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