當兩個sql文本相同,而其他環境不同,這兩個遊標不能共享執行計劃。它們都有各自的執行計劃存在緩存庫中。這兩個遊標就是子游標,oracle還會建立一個父遊標,父遊標沒有執行計劃,只是文本相同但執行計劃不同的所有遊標的代表。
其實在庫緩存中,即使一個遊標沒有和它文本相同的其它遊標,oracle也會爲每個遊標創建父遊標。也就是說只要你執行SQL語句,oracle都會在庫緩存中保存一父一子兩個遊標。如果你執行了文本相同但環境不同因此不能共享執行計劃的SQL語句,那麼一個父遊標就對應多個子遊標。
父遊標沒有執行計劃,只有一些信息管理性數據,oracle添加它的目的就是爲了管理文本相同的遊標。
V$sqlarea: 保留SQL語句的父遊標信息,可以通過SQL_ID標識,其中version_count列表示子游標的數量
V$SQL: 保留SQL語句的子游標信息,可以通過SQL_ID和child_number標識
注意v$sql中的子游標的編號是由0開始的
V$SQL_shared_cursor: 語句產生子游標的原因
這裏再解釋下可以更清楚理解概念:
scott 用戶下執行以下SQL:
select * from emp;
sh 用戶下執行以下SQL:
select * from emp;
以上兩個SQL一模一樣,而他們執行的用戶不同,甚至這兩個EMP都屬於不同schema,那麼此時的在v$sqlarea他們同用一個父遊標,在這個父遊標下面查詢v$sql有兩個子游標。
關於遊標的結構與原理請參考:基於Oracle的SQL優化