11G result cache新特性的更多深入研究
前面一個帖子,探討了一些11G result cache的一些可能沒被人所注意到的一些發現。
http://space.itpub.net/15415488/viewspace-615398
而這個帖子是在經過team meeting大家提出的疑問之後,
而對result cache做出的一些更加深入的研究和分析。
在team meeting中同事提出了一些問題,而這裡先對這些問題做出一些解答。
--------------FAQ Part---------------
Q1:更新其他的行、或者更新其他block中的行 會不會invalidate 這個result cache?
A1:會。任何DML/DDL(甚至包括grant)都會使基於這個object的result cache invalidate。
所以說,result cache他的依耐性是object level的,既不是row level的,也不是block level的。
這樣的話,我認為result cache只有對那些在平時幾乎沒有任何DML的只讀表比較有用。
Q2:result cache使用什麼latch保護?是不是用的shared pool latch?
A2:在平時讀取階段不是使用的shared pool latch,而是使用的result cache latch。
SQL> select * from v$latchname where name like 'Result Cache%';
LATCH# NAME HASH
---------- ------------------------------ ----------
373 Result Cache: Latch 1545889529
374 Result Cache: SO Latch 986859868
Q3:result cache有enqueue/lock保護麼?
A3:是的。RC enqueue就是拿來保護併發修改的。
例如當我們建立一個新的result cache時。
SQL> select distinct ksqsttyp,ksqstexpl from x$ksqst where KSQSTEXPL like '%result%' order by ksqsttyp;
KS
--
KSQSTEXPL
--------------------------------------------------------------------------------
RC
Coordinates access to a result-set
Q4:使用result cache有什麼overhead麼?
A4:我做了一個簡單的實驗來得到他的overhead:
SQL> set timing on
SQL> exec sys.runstats_pkg.rs_start;
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.19
-- 下面的PLSQL不使用result cache來查詢100000次。
SQL> DECLARE
2 v_name varchar2(100);
3 BEGIN
FOR i IN 1 .. 100000 LOOP
select name into v_name from testbyhao where id=1000;
END LOOP;
END;
/ 4 5 6 7 8
PL/SQL procedure successfully completed.
Elapsed: 00:00:10.31
SQL> exec sys.runstats_pkg.rs_middle;
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.02
--下面的PLSQL我使用result cache來查詢100000次。
SQL> DECLARE
2 v_name varchar2(100);
3 BEGIN
FOR i IN 1 .. 100000 LOOP
select /*+result_cache*/ name into v_name from testbyhao where id=1000;
END LOOP;
END;
/ 4 5 6 7 8
PL/SQL procedure successfully completed.
Elapsed: 00:00:08.85
--然後下面對比兩種方式的statistics的差異(只取差值>1000的)
SQL> exec sys.runstats_pkg.rs_stop(1000);
Run1 ran in 1565 hsecs
Run2 ran in 1603 hsecs
run 1 ran in 97.63% of the time
Name Run1 Run2 Diff
STAT...session uga memory 8,144 3,880 -4,264
STAT...calls to kcmgrs 100,044 54 -99,990
STAT...rows fetched via callba 100,000 2 -99,998
STAT...table fetch by rowid 100,000 2 -99,998
STAT...index fetch by key 100,000 2 -99,998
LATCH.Result Cache: Latch 0 200,003 200,003
STAT...session logical reads 300,035 44 -299,991
STAT...consistent gets 300,011 19 -299,992
STAT...consistent gets from ca 300,011 19 -299,992
STAT...consistent gets - exami 300,005 12 -299,993
STAT...buffer is not pinned co 300,000 6 -299,994
Run1 latches total versus runs -- difference and pct
Run1 Run2 Diff Pct
1,349 201,389 200,040 .67%
PL/SQL procedure successfully completed.
我們可以很清楚地看到,在僅僅全部讀取result cache的情況下,
所帶來的overhead只在於更多的result cache latch。
而這個result cache latch他到底有多少個呢?
答案是1個,因為他們沒有latch children。
SQL> select count(*)2 from v$latch_children
3 where name='Result Cache: Latch';
COUNT(*)
----------
0
--------------End of FAQ Part---------------
--------------Viadea's分割線-----------------
-------------Other Finding Part--------------
經過閱讀國外很多牛人的實驗方法,再透過自己切身實驗,得到更多更深入的finding,
於是姑且將一些精華的東西分享給大家。
1.Trace result cache的event是:
ALTER SESSION SET EVENTS '43905 trace name context forever, level 1';
得到的結果類似於:
*** 2009-09-28 06:45:46.101
Objects for this node : 24006
-------------------------------------
Query[len=44]: SELECT /*+result_cache*/ NAME FROM TESTBYHAO
Normalized Query[len=25]: 172 670 70 1?"TESTBYHAO"
Cache id1: at33rkq5njw4z12qkkp17rwctj
Cache id2: at33rkq5njw4z12qkkp17rwctj
Column count: 1
NLS Dependent: NO User Referenced: NO Ordered: NO Auto: NO
Dependencies: (24006 - HAOZHU_USER.TESTBYHAO)
2.result cache 的background process是:
SQL> select name,description from V$BGPROCESS where name like 'RC%';
NAME DESCRIPTION
----- ----------------------------------------------------------------
RCBG Result Cache: Background
3.每次存取(讀) result cache會得到2次latch。
SQL> select gets, misses, sleeps, wait_time
2 from v$latch
3 where name = 'Result Cache: Latch';
GETS MISSES SLEEPS WAIT_TIME
---------- ---------- ---------- ----------
601597 0 0 0
Elapsed: 00:00:00.01
SQL> DECLARE
2 v_name varchar2(100);
3 BEGIN
FOR i IN 1 .. 100000 LOOP
select /*+result_cache*/ name into v_name from testbyhao where id=1000;
END LOOP;
END;
/ 4 5 6 7 8
PL/SQL procedure successfully completed.
Elapsed: 00:00:08.77
SQL> select gets, misses, sleeps, wait_time
2 from v$latch
3 where name = 'Result Cache: Latch';
GETS MISSES SLEEPS WAIT_TIME
---------- ---------- ---------- ----------
801597 0 0 0
Elapsed: 00:00:00.01
SQL>
SQL> select (801597-601597)/100000 from dual;
(801597-601597)/100000
----------------------
2
4.每次修改(例如新建一個result cache)會得到4次latch:
SQL> select count(*) from testbyhao;
COUNT(*)
----------
4000
SQL> select gets, misses, sleeps, wait_time
2 from v$latch
3 where name = 'Result Cache: Latch';
GETS MISSES SLEEPS WAIT_TIME
---------- ---------- ---------- ----------
817699 0 0 0
Elapsed: 00:00:00.01
SQL> DECLARE
2 v_name varchar2(100);
3 begin
for cur in (select * from testbyhao)
loop
select /*+result_cache*/ name into v_name from testbyhao where id=cur.id;
end loop;
end; 4 5 6 7 8
9 /
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.75
SQL> select gets, misses, sleeps, wait_time
2 from v$latch
3 where name = 'Result Cache: Latch';
GETS MISSES SLEEPS WAIT_TIME
---------- ---------- ---------- ----------
833698 0 0 0
Elapsed: 00:00:00.01
SQL> select (833698-817699)/4000 from dual;
(833698-817699)/4000
--------------------
3.99975
5.重要引數_result_cache_timeout和enq: RC - Result Cache: Contention的關係。
_result_cache_timeout預設值是60s,代表著一個session等待得到result cache多少秒。
下面的例子非常經典,我拿來主義自己測了一把。
--第一個session我讓他試圖建立一個result cache,但讓他一直保持“NEW”的狀態。
--這樣其他session的同一條語句就沒法獲得這個enqueue。
Session A:
SQL> variable rc refcursor;
SQL> exec open :rc for select /*+ result_cache */ id from testbyhao2;
PL/SQL procedure successfully completed.
SQL> set serveroutput on
SQL> exec rc_fetch(:rc);
1469
PL/SQL procedure successfully completed.
--我們可以看到Session A拿到了這個RC enqueue,沒有釋放.
SQL> select sid, type, id1, id2, lmode
2 from v$lock
where sid=sys_context('userenv', 'sid'); 3
SID TY ID1 ID2 LMODE
---------- -- ---------- ---------- ----------
318 RC 1 1 6
318 AE 99 0 4
--從v$result_cache_objects,可以看到當前這個result cache的狀態時NEW,並不是published。
SQL> /
STATUS NAME PIN_COUNT SCAN_COUNT
--------- -------------------------------------------------------------------------------------------------------------------------------- ---------- ----------
CACHE_ID
---------------------------------------------------------------------------------------------
CACHE_KEY
---------------------------------------------------------------------------------------------
Published HAOZHU_USER.TESTBYHAO2 0 0
HAOZHU_USER.TESTBYHAO2
HAOZHU_USER.TESTBYHAO2
New SELECT /*+ result_cache */ ID FROM TESTBYHAO2 2 0
0632rwbj2n03pfp9gymdv0ck68
6s5papz2k5hw4dkgus2h8yx9jr
Session B:
--從Session B再run同一條語句,而這條語句會試圖得到RC enqueue
SQL> set serveroutput on
SQL> set timing on
SQL> variable rc refcursor;
SQL> exec open :rc for select /*+ result_cache */ id from testbyhao2;
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.01
SQL> exec rc_fetch(:rc);
1469
PL/SQL procedure successfully completed.
Elapsed: 00:01:01.38
--我們可以看到Session B在執行如此簡單的一條語句的時候居然等待了60s,
--而這個時間就是我們的_result_cache_timeout。
--當Session B沒能獲得他所希望的RC enqueue之後,他就會Bypass這個result cache,
--然後自己使用正常的執行方式獲得想要的答案。
--在Session B等待的這60s中,我看到了所希望看到的result cache contention。
TEST > ora10 active
9:16am up 264 day(s), 11:19, 10 users, load average: 0.34, 0.32, 0.32
SID USERNAME MACHINE EVENT PARAM W WT SQL ST LT LOGON_TIME STATE
------ ---------- ------------------------------ ------------------------------ -------------------- ---- ---- ------------------------ -- ------ ---------- -------------------
636 HAOZHU_USE enq: RC - Result Cache: Conten 1380122628/1/1 0 4 2393857412/1029988163 A 15 53 WAITING
SQL> /
STATUS NAME PIN_COUNT SCAN_COUNT
--------- -------------------------------------------------------------------------------------------------------------------------------- ---------- ----------
CACHE_ID
---------------------------------------------------------------------------------------------
CACHE_KEY
---------------------------------------------------------------------------------------------
Published HAOZHU_USER.TESTBYHAO2 0 0
HAOZHU_USER.TESTBYHAO2
HAOZHU_USER.TESTBYHAO2
Bypass SELECT /*+ result_cache */ ID FROM TESTBYHAO2 1 0
0632rwbj2n03pfp9gymdv0ck68
6s5papz2k5hw4dkgus2h8yx9jr
所以,result cache作為一個足夠吸引人的new feature,也帶來了一個新的現象:
Readers blocks Readers。
為了降低這種block的機率,DBA可以根據自己一段時間的monitor的資料,適當的降低_result_cache_timeout的大小。
6.為了感謝各位的捧場,特地再奉上一本講result cache internal的PPT。
裡面主要講解了result cache的記憶體結構、演算法的更加深入的東西。
喜歡研究更細緻的同學可以看看。
----------End of Other Finding Part----------
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15415488/viewspace-615873/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle 11g新特性:Result CacheOracle
- SQL Query Result Cache的使用和配置--Oracle 11G新特性SQLOracle
- 11g新特性--result caching
- 11G result cache新特性的一些發現和個人見解
- Oracle11g新特性:SQL Result Cache [zt]OracleSQL
- 【11gR2新特性】result cache 的三種模式模式
- query result cache in oracle 11gOracle
- 聊聊Oracle 11g的Result Cache(一)Oracle
- 聊聊Oracle 11g的Result Cache(二)Oracle
- 聊聊Oracle 11g的Result Cache(三)Oracle
- 聊聊Oracle 11g的Result Cache(四)Oracle
- oracle 11g result_cache分析Oracle
- ORACLE 11g Result cache使用指南Oracle
- 【11gR2新特性】DBMS_RESULT_CACHE管理結果快取的包快取
- Oracle 11gR2 Result Cache特性文章收集Oracle
- 11g result cache 結果快取記憶體快取記憶體
- Oracle 11g 的server結果快取result_cache_modeOracleServer快取
- Oracle Query Result CacheOracle
- Oracle 11.2.0.1 Result Cache 測試 - 12 DBMS_RESULT_CACHE管理包Oracle
- Oracle 宣佈更多的 Java 9 新特性OracleJava
- Oracle宣佈更多的Java 9 新特性OracleJava
- 淺談Oracle Result CacheOracle
- Using Oracle Database 11g Release 2 Result Cache in an Oracle RAC EnvironmentOracleDatabase
- 【ORACLE新特性】11G 分割槽新特性Oracle
- oracle 11g 的新特性Oracle
- Oracle 11g 新特性Oracle
- Google IO/19 - Kotlin 1.3,更多新特性GoKotlin
- 11g data guard 新特性
- 11g新特性--active dataguard
- 11G新特性:FLASHBACK ARCHIVEHive
- 12c設定RESULT_CACHE_MODE=MANUAL發生'Result Cache:RC Latch'型別的Latch Free等待型別
- oracle result cache 結果集快取的使用Oracle快取
- 使用RESULT CACHE加速SQL查詢效率SQL
- Oracle 11.2.0.1 Result Cache 測試 - 1Oracle
- Oracle 11.2.0.1 Result Cache 測試 - 5Oracle
- Oracle 11.2.0.1 Result Cache 測試 - 6Oracle
- Oracle 11.2.0.1 Result Cache 測試 - 7Oracle
- Oracle 11.2.0.1 Result Cache 測試 - 8Oracle