【DB筆試面試577】在Oracle中,游標有哪幾類?
- 2019 年 10 月 10 日
- 筆記
♣
題目部分
在Oracle中,游標有哪幾類?
♣
答案部分
游標(Cursor)是Oracle資料庫中SQL解析和執行的載體,它可以分為共享游標(Shared Cursor)和會話游標(Session Cursor)。共享游標是指快取在庫快取(Library Cache)里的一種庫快取對象,其實就是指快取在庫快取里的SQL語句和匿名PL/SQL塊所對應的庫快取對象。共享游標是Oracle快取在庫快取中的幾十種庫快取對象之一,它所對應的庫快取對象句柄的Namespace屬性的值是CRSR(也就是Cursor的縮寫)。共享游標會存儲目標SQL的SQL文本、解析樹、該SQL所涉及的對象定義、該SQL所使用的綁定變數類型和長度,以及該SQL的執行計劃等資訊。共享游標可以細分為父游標(Parent Cursor)和子游標(Child Cursor),可以通過視圖V$SQLAREA來查看當前快取在庫快取(Library Cache)中的父游標,而通過V$SQL來查看快取在庫快取中的子游標。Oracle設計這種嵌套的Parent Cursor和Child Cursor並存的結構是為了能盡量減少對應的Hash Bucket中庫快取對象句柄鏈表的長度。
Oracle中游標的分類如下圖所示:

圖 3-13 Oracle中的游標分類
父游標和子游標的對比如下表所示:
|
父游標(Parent Cursor) |
子游標(Child Cursor) |
---|---|---|
查詢視圖 |
V$SQLAREA |
V$SQL |
存儲內容 |
父游標存儲SQL文本(庫快取對象句柄的屬性NAME中);父游標的 heap 0 中存儲著子游標的句柄地址。 |
子游標存儲解析樹(Parse Tree)及執行計劃(Execution Plan,實際上存儲在庫快取對象句柄的heap 6中),以及該SQL所使用的綁定變數的類型和長度。 |
庫快取對象句柄的屬性NAME存儲內容 |
存儲SQL文本 |
空 |
聯繫 |
1.父游標和子游標的結構是一樣的,它們都是以庫快取對象句柄的方式快取在庫快取中,Namespace屬性的值均為CRSR。2.由於子游標所對應的庫快取對象句柄的NAME屬性值為空,所以,只能通過父游標才能找到相應的子游標。3.任意一個經過解析的目標SQL一定會同時對應兩個共享游標(Shared Cursor),一個是父游標(Parent Cursor),另一個則是子游標(Child Cursor)。 |
Oracle在解析目標SQL時去庫快取中查找匹配Shared Cursor的過程如下圖所示:

從上圖可以看出,Oracle在解析目標SQL時去庫快取中查找匹配共享游標(Shared Cursor)的過程包含如下幾個步驟:
(1)根據目標SQL的SQL文本的哈希值去庫快取中查找匹配的Hash Bucket。
(2)然後在匹配的Hash Bucket的庫快取對象鏈表中查找匹配的父游標(Parent Cursor),當然,在查找匹配Parent Cursor的過程中肯定會比對目標SQL的SQL文本(因為不同的SQL文本計算出來的哈希值可能是相同的)。
(3)在步驟(2)中,如果找到了匹配的父游標,那麼Oracle接下來就會遍歷從屬於該父游標的所有子游標以查找匹配的子游標。如果找不到匹配的父游標,那麼也意味著此時沒有可以共享的解析樹和執行計劃,Oracle就會從頭開始解析上述目標SQL,新生成一個父游標和一個子游標,並把它們掛在對應的Hash Bucket中。在匹配的父游標中查找匹配的子游標時,如果找到了匹配的子游標,那麼Oracle就會把存儲於該子游標中的解析樹和執行計劃直接拿過來重用,而不用再從頭開始解析。如果找不到匹配的子游標,那麼意味著沒有可以共享的解析樹和執行計劃,接下來Oracle也會從頭開始解析上述目標SQL,新生成一個子游標,並把這個子游標掛在對應的父游標下。
本文選自《Oracle程式設計師面試筆試寶典》,作者:李華榮。