共享池之五:Shared Pool子池與結果集快取技術

還不算暈發表於2014-03-15

SubPool技術及優勢:

從Oracle 9i開始,Shared Pool可以被分割為多個子緩衝池(SubPool)進行管理,以提高併發性,減少競爭。
Shared Pool的每個SubPool可以被看作是一個Mini Shared Pool,擁有自己獨立的Free List、記憶體結構以及LRU List、shared pool latch。同時Oracle提供多個Latch對各個子緩衝池進行管理,從而避免單個Latch的競爭(Shared Pool Reserved Area同樣進行分割管理)。從10G開始,每個SubPool由4個SUB PARTITION組成。

SubPool的個數和大小

每四個CPU分配一個SubPool,最多可以有7個。Shared Pool Latch也就從原來的一個增加到現在的7個。
在Oracle 9i中,每個SubPool至少為128MB。
10G-10.2.0.3,每個SubPool至少為256MB
10.2.0.3之後,最少為512M。
_kghdsidx_count 隱含引數:ORACLE啟動時,優化根據此引數設定SubPool數量。

SubPool缺點:

從ORACL 10G開始,ORACLE程式在某個SubPool中請求記憶體失敗,會到下一個SubPool中請求---過小的SubPool碎片問題可能更嚴重--ORA-4031出現機率更大。
過多的SubPool還會帶來更高的管理協調成本。
比如以下錯誤就是與SubPool相關:
ORA-04031: unable to allocate 4216 bytes of shared memory
("shared pool","unknown object","sga heap(2,0)","library cache")

共享池大小的判斷

        LRU連結串列分兩條:transient LRU(瞬時LRU)、 RECURRENT(週期LRU)。Chunk在第一次使用時,被放入瞬時LRU,第二次使用時,會被移至週期LRU。

        DSI中建議用如下SQL統計LRU和相關資訊:
select KGHLUTRN transient,KGHLURCR recurrent ,KGHLUFSH Flush_chunk_number, KGHLUOPS Pin_or_release_operations from X$KGHLU;
--查詢出的是自資料庫啟動以來的,執行ALTER SYSTEM FLUSH SHARED_POOL不會清零。
其中:
    TRANSIENT,瞬時LRU鏈長度。
    RECURRENT,週期LRU鏈長度。
    FLUSH_CHUNK_NUMBER,Flush Chunk數。
    PIN_OR_RELEASE_OPERATIONS,Pin或釋放Chunk操作的次數。
        如果瞬時LRU鏈長度超過週期LRU鏈長度3倍,大量只用一次的Chunk堆積在LRU中,說明共享池太大了。
        如果Flush Chunk數和Pin、釋放Chunk操作次數的比小於1:20,說明共享池太小了。這個比例,簡單點說,Oracle認為每20次操作Chunk,只有一次Flush Chunk操作,還是可以接受的。如果再低,說明共享池有點小。

######Chunk數和Pin、釋放Chunk操作次數的比小於1:20,說明共享池太小了。
這一句錯了吧,應該是大於20分之1(每20次操作有一次需要FLUSH CHUNK)時,如十分之1(每十次操作需要一次需要FLUSH CHUNK),說明共享池太小。
共享池一般不超過10G,5、6G即可。過大共享池需要更大管理成本
#####################################################################

結果集快取--RESULT CACHE

DB_BUFFER只能快取訪問過的BLOCK,部分解決了物理讀的問題,查詢仍然需要大量的邏輯讀。
物化檢視提供的是查詢重寫的功能,對於大部分的情況,只是簡化了SQL的複雜度,即使是完全滿足查詢的條件,物化檢視的掃描也是不可避免的。
而快取結果集——RESULT CACHE則截然不同,它快取的是查詢的結果。不在需要大量的邏輯讀,不在需要任何的複雜計算,而是直接將已經快取的結果返回。---SQL的幾乎全部開銷都可以避免。這些開銷包括,解析時間、邏輯讀、物理讀和任意的通常可能會遭遇的爭用。

RESULT CACHE的結果對於所有的SESSION都是可見的。
RESULT CACHE是滿足一致性讀的,而且當快取表資料發生變化的時候,Oracle會自動INVALIDATE快取結果集:

是否使用RESULT_CACHE與Oracle的執行計劃無關:
RESULT CACHE忽略SQL語句的執行計劃,即使執行計劃發生了變化,只有最終獲取的結果是一樣的,Oracle仍然會使用RESULT CACHE。
注意當執行計劃不同導致結果不同時,Oracle使用RESULT CACHE可能會得到不正確的結果。

對於SQL中間結果使用RESULT CACHE必須使用RESULT_CACHE提示進行強制。
RESULT CACHE功能對於下列情況是無效的:系統表和臨時表;序列的NEXTVAL和CURRVAL偽列;SYSDATE、SYSTIMESTAMP等函式;所有非確定性PL/SQL函式。

RESULT_CACHE和NO_RESULT_CACHE

Oracle新增了兩個HINT,RESULT_CACHE和NO_RESULT_CACHE。通過這兩個提示,可以明確的指出下面的語句是否進行RESULT CACHE。

Oracle還增加了幾個初始化引數來管理RESULT CACHE功能,如:RESULT_CACHE_MODE、RESULT_CACHE_MAX_SIZE等。
RESULT_CACHE_MAX_SIZE指明SGA中RESULT CACHE功能可以使用的最大的記憶體容量。如果這個引數設定為0,則關閉RESULT CACHE功能。
RESULT_CACHE_MODE引數設定Oracle如何使用RESULT CACHE,有三個值:MANUAL、AUTO、FORCE。
當引數值設定為MANUAL時,只有通過HINT明確提示的SQL才會讀取快取結果集。如果不加提示,那麼Oracle不會利用已經快取的結果。
對於AUTO模式,Oracle如果發現緩衝結果集已經存在,那麼就會使用。但是如果緩衝結果集不存在,Oracle並不會自動進行緩衝。只有使用HINT的情況下,Oracle才會將執行的結果集快取。
對於FORCE引數,就是會對所有的SQL進行快取,除非明確使用NO_RESULT_CACHE提示:
result_cache_max_result設定單個sql語句佔用整個RESULT CACHE緩衝區的百分比,預設5%。
RESULT_CACHE_MAX_SIZE用來設定RESULT CACHE的總體大小--不超過過SHARED_POOL_SIZE的75%

在11.2.0.4中,預設是:MANUAL
BYS@ bys3>show parameter result_cache_mode
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
result_cache_mode                    string      MANUAL
Oracle提供了DBMS_RESULT_CACHE包來管理和維護RESULT CACHE。
Oracle還新增了幾個關於RESULT CACHE的系統檢視,使用者可以看到和RESULT CACHE相關的各種資訊,檢視包括:V$RESULT_CACHE_DEPENDENCY、V$RESULT_CACHE_MEMORY、V$RESULT_CACHE_OBJECTS和V$RESULT_CACHE_STATISTICS等。
關於結果集快取詳見:
http://www.itpub.net/thread-846890-1-1.html
http://database.ctocio.com.cn/tips/365/8273865.shtml

相關文章