1. 개요

Result Cache는 11g에 새롭게 추가된 기능으로 SQL Query의 결과나 PL/SQL function의 결과를 메모리 내에 cache할 수 있는 기능이다.
Result Cache는 result가 무엇의 결과이냐에 따라, 그리고 cache가 어디에 존재하는지에 따라 다음과 같이 분류 된다.

  • SQL Query Result Cache
  • Server-side
  • Client-side
  • PL/SQL Function Result Cache
  • Server-side

1.1 Query Result

다음과 같은 Query Result는 Cache에 저장된다.

  • 일반적인 SQL Query
  • 특정 시점에 대한 flashback query도 cache된다.
  • query 결과가 read-consistent 한 snapshot이라면 cache의 대상이 된다.
  • view 또는 inline view 형태의 query block도 cache된다.

다음과 같은 Query Result는 Cache에 저장되지 않는다.

하나의 트랜잭션에서 변경과 조회가 동시에 발생하는 경우

참고
subquery의 결과는 단독으로 cache되지 않으며, view/inline view에 대한 optimization은 disable된다.

1.2 Cache

Query Result를 저장하는 Cache영역은 shared pool 영역에 저장된다.

[SIZING]
다음과 같은 기본값으로 shared pool내에 할당된다.

  • MEMORY_TARGET 사용 시: MEMORY_TARGET의 0.25%
  • SGA_TARGET 사용 시: SGA_TARGET의 0.5%
  • SHARED_POOL_SIZE 사용 시: SHARED_POOL_SIZE의 1%

[RESULT_CACHE_MAX_SIZE]
result cache의 크기를 명시적으로 지정하고자 하는 경우 사용하는 파라메터이다.

  • 최소값은 0 : disable된다.
  • 최대값 : shared pool크기의 75%이다.

주의
원래 동적 변경이 가능한 파라메터이지만, 이 파라메터의 값을 0으로 설정하여 instance를 시작하면 alter system 명령으로 수정할 수 없다.

[RESULT_CACHE_MAX_RESULT]
전체 result cache memory내에서 하나의 result가 가질 수 있는 메모리의 체대 크리를 지정하는 파라메터로 전체 크기에 대한 %로 값을 지정할 수 있다. 기본값은 5%이다.

2. Result Cache의 동작

Query Result Cache의 동작은 크게 3가지로 나누어 볼 수 있다.

  • Cache-in
  • Cache-hit
  • Cache-out

2.1 Query Result Cache

일반 Query에서 동작 상황을 보자.

2.1.1 Cache-in

Cache안에 데이터가 저장되는 동작을 말하는 것으로 이를 결정하는 1차적인 요소는 System/session level 파라메터인 RESULT_CACHE_MODE이다.

[RESULT_CACHE_MODE]
2가지로 설정이 가능하다.

  • MANUAL
    이 값을 설정하는 경우 SQL마다 /*+result_cache*/힌트를 주어야 한다.
    이 값이 default이다.
  • FORCE
    모든 SQL이 result caching 대싱이 된다. 반대로 /\*+no_result_cache\*/ 힌트를 주어야 만 cache되지 않게 할 수 있다.
    다음과 같이 설정하고 SQL이 실행되면 cache-in은 다음의 두 조건을 모두 만족하는 경우에 발생한다.
    • 현재의 결과가 cache되어있지 않다.
    • 결과의 크기가 RESULT_CACHE_MAX_RESULT이하 이다.

제약사항
다음의 쿼리들은 result cache가 되지 않는다.

  • Dictionary 및 temporary table에 대한 쿼리
  • sequence의 CURVAL/NEXTVAL에 대한 쿼리
  • current_date, current_timestamp, local_timestamp, userenv/sys_context(with non_constant variables)
  • sys_guid, sysdate, sys_timestamp등의 함수 호출이 포함된 쿼리
  • non-deterministic PL/SQL 함수를 호출하는 쿼리
2.1.2 Cache-hit

Cache안에 정보를 재사용하는 동작을 말한다. 먼저, 동일한 SQL이 수행되어야 하며, 동시에 파라메터도 동일해야 한다.

여기서 말하는 파라메터는 다음을 말한다.

  • Bind 변수
  • dbtimezone, sessiontimezone, userenv/sys_context(with constant variables), uid, user등의 보다 정적인 함수 호출 결과
  • NLS등의 환경 파라메터들

참고
RAC환경하에서 result cache의 cache hit은 어디까지나 local event이다. 즉 각각 각자의 내용을 담고 있다는 것이다.

2.1.3 Cache-out

Cache안의 정보가 cache에서 나오는 것을 말한다. 다음과 같은 경우에 out된다.

  • age-out : result cache 역시 LRU cache이기 때문이다.
  • Invalidation: 해당 query가 참조하는 object에 DML등의 변경이 일어나는 경우 발생한다.

참고
RAC환경에서 result cache의 cache-hit은 local event이지만, invalidation은 global event이다. 이는 read consistency의 문제이기 때문이다.

2.2 PL/SQL Function Result Cache

PL/SQL function result cache는 SQL query result cache 기능과 구조를 공유한다. Cache도 shared pool의 result cache memory 영역내에 SQL Query 용과 PL/SQL function 용으로 나누어져서 사용할 뿐이다.
그러므로 여기서는 차이점에 대한 것만 기술한다.

2.2.1 Cache-in

PL/SQL function은 SQL과 다르게 힌드를 사용하지 않고 다음의 서명을 사용함으로 result caching을 하게 된다.

제약 사항은 다음과 같다.

  • IN parameter 중 BLOB, CLOB, NCLOB, REF CURSOR, Collection, Object, Record 타입이 있으면 안된다.
  • Return 타입이 BLOB, CLOB, NCLOB, REF CURSOR, Object 이거나, BLOB, CLOB, NCLOB, REF CURSOR, OBJECT타입을 포함하는 Record또는 Collection인 경우도 안된다.
  • OUT/IN OUT parameter를 가진 경우도 안된다.
  • Invoker's right로 정의된 경우 또는 anonymous block내에서 정의된 경우도 안된다.

참고
Recursive function 역시 cache될 수 있다. 만약, cache된 recursive function이 호출되면 일체의 재귀적 호출은 생략된다.

2.2.2 Cache-hit

Cache hit이 되기 위해서는 다음과 같은 조건이 만족되어야 한다.
"동일한 함수, 동일한 parmeter"

2.3 Client-side SQL Query Result Cache

Oracle 11g의 result cache기능은 Client단의 cache도 가능하다. Client단 cache는 다음의 장점이 있다.

  • Client-Server 사이의 rount trip을 제거하는 효과가 있다.
  • 응답 시간이 크게 향상된다.
  • 서버 단의 CPU나 메모리 사용량을 낮출 수 있다.

다음의 query 들은 cache되지 않는다.

  • View
  • Remote object
  • Complex types in the select list
  • Snapshot-based or flashback queries
  • Queries executed in a serializable, read-only transaction, or inside a flashback session
  • Queries that have PL/SQL functions in them
  • Queries that have VPD policies enabled on the tables
2.3.1 사용법

Client 단에서 Cache하기 위해서는 다음의 parameter를 설정해야 한다.

[CLIENT_RESULT_CACHE_SIZE]
하나의 클라이언트 프로세스가 가질 수 있는 result cache의 최대 크기를 지정한다. 0으로 지정하면 disable된다. Sqlnet.ora 파라미터인 OCI_RESULT_CACHE_MAX_SIZE를 통해 override할 수 있다.

[CLIENT_RESULT_CACHE_LAG]
클라이언트 result cache가 서버단의 변경에 대해 가질 수 있는 lag의 최대값으로 기본은 3초 이다.
이 외에도 OCI Statement Caching기능을 꼭 enable해야 한다.

[정보 확인하기]
CLIENT_RESULT_CACHE_STATS$을 통해 통계를 확인할 수 있다.

3. Query Result Cache의 모니터링

다음과 같이 모니터링이 가능하다.

[DBMS_RESULT_CACHE]
다음의 패키지를 사용하여 result cache에 대한 정보나 통계는 물론 각종 관리 작업도 수행할 수 있도록 하는 다양한 프로시져들을 제공한다.

[View]
다음의 View를 통해 관련 정보를 확인할 수 있다.

  • (G)V$RESULT_CACHE_STATISTICS
  • (G)V$RESULT_CACHE_MEMORY
  • (G)V$RESULT_CACHE_OBJECTS
  • (G)V$RESULT_CACHE_DEPENDENCY

4. Query Result Cache 예제

4.1 Query에 대한 Result Cache 예제 보기

4.1.1 상태 확인

다음과 같이 현재 상태를 확인하는 것이 가능하다.


SQL> connect / as sysdba
Connected.
SQL> SET FEEDBACK 1
SQL> SET NUMWIDTH 10
SQL> SET LINESIZE 150
SQL> SET TRIMSPOOL ON
SQL> SET TAB OFF
SQL> SET PAGESIZE 1000
SQL> SET SERVEROUTPUT ON
SQL>
SQL> show parameter result_cache_mode
NAME TYPE VALUE
------------------------------------ ---------------------- ------------------------------
result_cache_mode string MANUAL
SQL> show parameter memory_target
NAME TYPE VALUE
------------------------------------ ---------------------- ------------------------------
memory_target big integer 412M
SQL> show parameter result_cache_max_size
NAME TYPE VALUE
------------------------------------ ---------------------- ------------------------------
result_cache_max_size big integer 1056K - default; memory_target의 약0.25%
SQL> show parameter result_cache_max_result
NAME TYPE VALUE
------------------------------------ ---------------------- ------------------------------
result_cache_max_result integer 5
SQL>
SQL> execute dbms_result_cache.flush; -- result cache를 flush
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.01
SQL> alter system flush shared_pool;
System altered.
Elapsed: 00:00:00.34
SQL> execute dbms_result_cache.memory_report; -- result cache 현황 파악
R e s u l t C a c h e M e m o r y R e p o r t
[Parameters]
Block Size = 1K bytes -- 내부적으로 1KB 단위로 관리 (not configurable)
Maximum Cache Size = 1056K bytes (1056 blocks) -- result_cache_max_size에 대응
Maximum Result Size = 52K bytes (52 blocks) -- result_cache_max_result에 대응
[Memory]
Total Memory = 5132 bytes [0.003% of the Shared Pool]
... Fixed Memory = 5132 bytes [0.003% of the Shared Pool]
... Dynamic Memory = 0 bytes [0.000% of the Shared Pool] -- 0; 현재 cache된 result가 없음

4.1.2 실행계획 확인해 보기

실행계획을 확인해 보면 다음과 같이 "RESULT CACHE" 라는 새로운 row source operation이 추가되어 보임을 확인할 수 있다.

4.1.3 실제 실행 후 결과 보기

실제로 쿼리를 실행 후에 결과를 보면 다음과 같이 확인이 가능하다.