結果集緩存
和聚合物化視圖類似,報表系統和數據倉庫系統是最適合結果集緩存的,這些系統通常具有大量復雜的SQL,其中不少子查詢包含聚合函數,如果能夠盡可能重用這些已經計算過的聚合結果集,將極大的提升系統性能並降低服務器負載。默認情況下,服務端結果集大小為共享池大小的0.5%,如果人工設置了共享池大小,則為1%,如果默認值不合適,可以調整result_cache_max_size,該參數聲明了用於結果集緩存的SGA大小,將該值更改為0可以禁用結果集緩存,此時通常是應用使用了物化視圖進行聚合查詢優化或沒有很多聚合查詢的OLTP系統。需要注意的是,結果集緩存默認是否啟用由result_cache_mode控制,參數聲明了Oracle如何管理結果集緩存的使用,默認為MANUAL,也就是SQL語句必須使用優化器提示才能使用結果集緩存;當設置為FORCE時表示所有獨立執行的語句都可以認為結果集緩存的候選。相對於聚合物化視圖可以針對整個表進行聚合,具體查詢中可以使用不同的group by字段作為條件重寫,結果集緩存只能根據具體的綁定變量進行,由於對子查詢塊抽象和判斷是否共用的成本較高,所以直接基於SQL塊的結果集緩存效果性價比在大部分情況下不算很好。
不過11g中PL/SQL函數新增的RESULT_CACHE子句更加有價值,傳統的DETERMINISTIC選項僅對於當前SQL語句引用的函數有效,而且不支持PL/SQL函數中調用其他PL/SQL函數。RESULT_CACHE剛好彌補了DETERMINISTIC的弱項,它使得在多個會話、不同的RAC節點、PL/SQL塊中都可以重用某個PL/SQL函數的執行結果,其使用如下:
create or replace function getXXXdays(v_tenantid in varchar2,
v_fundcode in varchar2,
v_agencyno in varchar2,
v_currentdate in varchar2,
n_offset in number,
n_skip in number := 1,
v_ageregion in number := 0)
return number deterministic
RESULT_CACHE RELIES_ON(ta_thkopenday) --只要加上RESULT_CACHE RELIES_ON子句即可,依賴數據源可以有多個,多個之間逗號分隔
is
result number(8);
begin
…
end;
/
我們有不少邏輯調用了一個計算交易日期的函數,這個函數又調用了其他很多函數,類似於下面的引用關系:
getintervaldays
gethkliqdays
gethkrealdays
getliqdays
getrealdays
我們僅通過為各函數增加RESULT_CACHE子句,性能就提升了10%。
如果啟用了結果集緩存特性,還需要注意,每個結果集緩存可用的內存大小並不是整個結果集緩存大小,而是受RESULT_CACHE_MAX_RESULT參數控制,其默認為RESULT_CACHE_MAX_SIZE的5%,因為結果集緩存本身的目的並非緩存大型SQL或子查詢的結果,所以通常最多增加到10%就足夠了,最后應定期監控v$result_cache_statistics和v$result_cache_objects確定結果集緩存的效果,以及是否有必要繼續開啟結果集緩存,還需要注意不要過多的在高並發的存儲過程以及函數上依賴於結果集緩存,它可能會導致latch free競爭嚴重,進而適得其反造成性能下降。
