父游標 子游標及共享游標

2022-08-03 09:33:12 字數 3463 閱讀 7655

游標是資料庫領域較為複雜的乙個概念,因為游標包含了shared cursor和session cursor。兩者有其不同的概念,也有不同的表現形式。

共享游標的概念易於與sql語句中定義的游標相混淆。本文主要描述解析過程中的父游標,子游標以及共享游標,即shared cursor,同時給出了

游標(session cursor)的生命週期以及游標的解析過程的描述。   

有關游標的定義,宣告,與使用請參考:pl/sql 游標

有關硬解析與軟解析請參考:oracle 硬解析與軟解析

一、相關定義

shared cursor

也即是共享游標,是sql語句在游標解析階段生成獲得的,是位於library cache中的sql或匿名的pl/sql等。其元資料被在檢視v$sqlarea

與v$sql中具體化。如果library cache中的父游標與子游標能夠被共享,此時則為共享游標。父游標能夠共享即為共享的父游標,子游

標能夠共享極為共享的子游標。

session cursor

即通過系統為使用者分配緩衝區用於存放sql語句的執行結果。使用者可以通過這個中間緩衝區逐條取出游標中的記錄並對其處理,直到所

有的游標記錄被逐一處理完畢。session cursor指的跟這個session相對應的server process的pga裡(準確的說是uga)的一塊記憶體區域

(或者說記憶體結構)即其主要特性表現在記錄的逐條定位,逐條處理。session cursor的元資料通過v$open_cursor檢視來具體化。每一

個開啟或解析的sql都將位於該檢視。

二、游標的生命週期(session cursor)

session cursor需要從uga中分配記憶體,因此有其生命週期。其生命週期主要包括:

開啟游標(根據游標宣告的名稱在uga中分配記憶體區域)

解析游標(將sql語句與游標關聯,並將其執行計畫載入到library cache)

定義輸出變數(僅當游標返回資料時)

繫結輸入變數(如果與游標關聯的sql語句使用了繫結變數)

執行游標(即執行sql語句)

獲取游標(即獲取sql語句記錄結果,根據需要對記錄作相應操作。游標將逐條取出查詢的記錄,直到取完所有記錄)

關閉游標(釋放uga中該游標占有的相關資源,但library cache中的游標的執行計畫按lru原則清除,為其游標共享提供可能性)

對於session cursor而言,可以將游標理解為任意的dml,dql語句(個人理解,有待核實)。即一條sql語句實際上就是乙個游標,只不過

session cursor分為顯示游標和隱式游標,以及游標指標。由上面游標的生命週期可知,任何的游標(sql語句)都必須經歷記憶體分配,解析,

執行與關閉的過程。故對隱式游標而言,生命週期的所有過程由系統來自動完成。對所有的dml和單行查詢(select ... into ...)而言,

系統自動使用隱式游標。多行結果集的dql則通常使用顯示游標。

二、游標的解析過程(產生shared cursor)

解析過程:

a、包含vpd的約束條件:

sql語句如果使用的表使用了行級安全控制,安全策略生成的約束條件新增到where子句中

b、語法、語義、訪問許可權檢查:

檢查sql語句書寫的正確性,物件存在性,使用者的訪問許可權

c、父游標快取:

將該游標(sql語句)的文字進行雜湊得到雜湊值並在library cache尋找相同的雜湊值,如不存在則生存父游標且儲存在library cache

中,按順序完成d-f步驟。如果此時存在父游標,則進一步判斷是否存在子游標。若存在相同的子游標,則直接呼叫其子游標的執行計

劃執行該sql語句,否則轉到步驟d進行邏輯優化   

d、邏輯優化:

使用不同的轉換技巧,生成語義上等同的新的sql語句(sql語句的改寫),一旦該操作完成,則執行計畫數量、搜尋空間將會相應增長。

其主要目的未進行轉換的情況下是尋找無法被考慮到的執行計畫

e、物理優化:

為邏輯優化階段的sql語句產生執行計畫,讀取資料字典中的統計資訊以及動態取樣的統計資訊,計算開銷,開銷最低的執行計畫將被

選中。f、子游標快取:

分配記憶體,生成子游標(即最佳執行計畫),與父游標關聯。可以在v$sqlarea, v$sql得到具體游標資訊,父子游標通過sql_id關聯

對於僅僅完成步驟a與b的sql語句即為軟解析,否則即為硬解析

三、shared cursor與session cursor的關係以及軟軟解析

關係:       

乙個session cursor只能對應乙個shared cursor,而乙個shared cursor卻可能同時對應多個session cursor

四、父游標與子游標、共享游標

由游標的解析過程可知,父游標,子游標同屬於共享游標的範疇。

父游標是在進行硬解析時產生的,父游標裡主要包含兩種資訊:sql文字以及優化目標(optimizer goal),首次開啟父游標被鎖定,直到其他

所有的session都關閉該游標後才被解鎖。當父游標被鎖定的時候是不能被lru演算法置換出library cache,只有在解鎖以後才能置換出

library cache,此時該父游標對應的所有子游標也同樣被置換出library cache。v$sqlarea中的每一行代表了乙個parent cursor,

address表示其記憶體位址。

子游標當發生硬解析時,在產生父游標的同時,則跟隨父游標會產生相應的子游標,此時v$sql.child_number的值為0。

如果存在父游標,由於不同的執行環境,此時同樣會產生新的子游標,新子游標的child_number在已有子游標基礎上以1為單位累計。

子游標包括游標所有相關資訊,如具體的執行計畫、繫結變數,object和許可權,優化器設定等。子游標隨時可以被lru演算法置換出

library cache,當子游標被置換出library cache時,oracle可以利用父游標的資訊重新構建出乙個子游標來,這個過程叫reload。

v$sql中中 的每一行表示了乙個child cursor,根據hash value和address與parent cursor 關聯。

child cursor有自己的address,即v$sql.child_address。

確定乙個游標的三個主要字段:address,hash_value,child_number,

五、演示父游標、子游標

六、總結

1、硬解析通常是由於不可共享的父游標造成的,如經常變動的sql語句,或動態sql或未使用繫結變數等

2、解決硬解析的辦法則通常是使用繫結變數來解決

3、與父游標sql文字完全一致的情形下,多個相同的sql語句可以共享乙個父游標

4、sql文字、執行環境完全一致的情形下,子游標能夠被共享,否則如果執行環境不一致則生成新的子游標

父游標 子游標及共享游標

游標是資料庫領域較為複雜的乙個概念,因為游標包含了shared cursor和session cursor。兩者有其不同的概念,也有不同的表現形式。共享游標的概念易於與sql語句中定義的游標相混淆。本文主要描述解析過程中的父游標,子游標以及共享游標,即shared cursor,同時給出了 游標 s...

父游標 子游標及共享游標

游標是資料庫領域較為複雜的乙個概念,因為游標包含了shared cursor和session cursor。兩者有其不同的概念,也有不同的表現形式。共享游標的概念易於與sql語句中定義的游標相混淆。本文主要描述解析過程中的父游標,子游標以及共享游標,即shared cursor,同時給出了 游標 s...

MySQL 游標 游標

游標cursor是用來儲存查詢結果集的 資料型別 在儲存過程和函式中可以使用游標對結果集進行迴圈的處理。游標的使用包括游標的宣告 open fetch 和 close,其語法分別如下 宣告游標 declare cursor name cursor for select statement open ...