遊標共用Cursor是Oracle學習過程中的一個重點和痛點。Oracle的Cursor是建立在對SQL解析Parse消耗的最佳化上的。根據不同的記憶體緩衝結構,我們經常可以聽到諸如:硬解析Hard Parse、軟解析Soft Parse和軟軟解析的名詞概念。
嚴格的說,遊標共用的概念基礎是遊標。Oracle中,遊標可以分為Shared Cursor和Private Cursor兩個大的類型。理解遊標的前提,一定要區分出這兩個遊標類型。
Oracle 自適應遊標共用--adaptive cursor sharing
Oracle 11g新SQL Trace 10046方法
1、Shared and Private Cursor
Shared Cursor大家談的比較多,就是駐留在Library Cache裡面的緩衝對象,其中儲存著之前解析好的執行計畫。當一個SQL語句第一次出現在系統中,Oracle在Library Cache中沒有找到對應的“現成”執行計畫,就會啟動硬解析Hard parse過程,在Library Cache中產生一個Shared Cursor。注意:這個SQL Cursor可以被其他“符合遊標共用條件”的其他會話session共用。在沒有被age out或者flush出記憶體前,都是可以共用。如果第二次發出相同SQL語句,共用了Shared Cursor,我們稱之為Soft Parse。
而與Shared Cursor對應的就是Private Cursor。Private Cursor是駐留在Server Process的PGA空間裡的。當我們發出SQL或者手工建立一個Cursor,都會在Server Process對應的PGA空間裡建立出一個Private Cursor對象。
顧名思義,Private Cursor的含義是只能被當前Session使用,不能實現session間共用。但是,相同一個Session,如果多次執行,是不是需要多次的建立Private Cursor呢?這個過程涉及到的問題就是Private Cursor的共用問題。
我們在一些資料裡面可以看到一些混淆概念。說一個SQL只有執行三次之上,才能進行共用。如果我們進行簡單的實驗,就可以發現這個論斷在shared cursor中並不成立。一旦SQL執行一次,在Library Cache中會去產生shared cursor,何來三次之說?應該說,這個論斷前提是Private Cursor共用。
2、軟軟解析和參數配置
我們接觸很多的概念是“Hard Parse”和“Soft Parse”。兩者的差異在於是否在Library Cache中發生執行計畫產生的動作。如果我們將Private Cursor因素考慮進去之後,就會有一個新的解析類型“軟軟解析”。
即使是Soft Parse,我們在PGA裡面,每次執行SQL的時候都會有Private Cursor的建立過程。按照Cursor生命週期,當Cursor執行結束之後,會有一個Close動作將Private Cursor失效。Oracle是可以嘗試對Private Cursor進行緩衝,也就是說,Close動作並不是真正關閉消失,而是可以支援共用Private Cursor。
如果可以實現Private Cursor在PGA中的重用,我們是可以將PGA中建立Cursor的部分成本消除掉。實現所謂的軟軟解析。
從Oracle早期開始,我們接觸過一個參數為open_cursor。最初這個參數起到兩個層面作用,其一是控制一個會話可以同時開啟的最大Cursor數量,另一個是控制了PGA裡面能夠共用Private Cursor緩衝的最大個數。
之後Oracle的設定出現了一些變化,引入了新參數session_cached_cursors,單獨進行緩衝區大小的限制。目前筆者實驗的版本中,這個參數是50。
SQL> show parameter cached
NAME TYPE VALUE
------------------------------------ ----------- ---------------
session_cached_cursors integer 50
對於PGA裡面的Private Cursor共用情況,Oracle會記錄產生的次數。當執行三次的時候,就會建立PGA內部緩衝的結構機制。
本篇中我們使用10046來驗證上面提到的機制。
3、環境準備
我們先找一個10046的Trace檔案作為實驗對象。選擇11.2.0.3作為實驗對象。
SQL> select value from v$diag_info where name='Default Trace File';
VALUE
--------------------------------------------------------------------
/u01/app/diag/rdbms/ora11g/ora11g/trace/ora11g_ora_6964.trc
清空shared pool和buffer cache,執行相同的SQL語句10次。
SQL> alter system flush shared_pool;
系統已更改。
SQL> alter system flush buffer_cache;
系統已更改。
SQL> alter session set events '10046 trace name context forever, level 12';
會話已更改。
SQL> select count(*) from t;
COUNT(*)
----------
0
SQL> select count(*) from t;
COUNT(*)
----------
0
(其餘執行次數略……)
SQL> alter session set events '10046 trace name context off';
會話已更改。
SQL>
產生了trace檔案之後,我們下面詳細分析這個檔案的細節。
更多詳情見請繼續閱讀下一頁的精彩內容: