<Insert Picture Here> Oracle Database 11g Result Cache 한국오라클 TSC 본부 김태형
<Insert Picture Here>
Oracle Database 11g Result Cache
한국오라클 TSC 본부김 태 형
2/72
Agenda
1. SQL Query Result Cache• Server-side• Client-side
2. PL/SQL Function Result Cache• Server-side
3. Client Side Result Cache
4. Database Resident Connection Pooling (DRCP)• Server-side pool
5. 기타 유용한 기능
• Adaptive Cursor Sharing
3/72
<Insert Picture Here>
1. SQL Result Cache• Server-side• Client-side
4/72
SQL Result Cache
SELECT …
Query Result Cache
SELECT …
Session 1 Session 2
• /*+result_cache*/
힌트를
사용하여
쿼리를
수행하여
result 를
저장
• 동일한
쿼리
수행시
테이블을
직접
조회하는
대신
캐시로
부터
결과를
가져오기
때문에
성능향상
기대
• 데이터
변경시
Cache는
자동으로
무효화
되기
때문에
SQL RESULT
CACHE 를
사용하더라도
항상
정확한
결과를
보장함
5/72
Server Results Cache 동작이해
• Query 결과, query 블록, PL/SQL function 결과 등을 Database 레벨에서 자동으로 캐쉬
• 캐쉬는 SQL 문장들, 세션들 사이에서 서로공유되고, 투명하게
사용됨
• 읽기 중심의 데이터에 대해 2배 이상의 성능 효과
Table 1
Table 2 Table 3
join
join
Group by
query 1 executes
Table 1
Table 2 Table 3
join
join
Group bycached result
result is cached
Table 5 Table 5
join
Table 4
join
Group by
joinquery 2 uses cached result transparently
6/72
SQL Result Cache 의 Memory
7/72
SQL Result Cache
8/72
SQL Result Cache 저장영역
• Result cache memory 는 SGA 의Shared Pool 영역 에 저장
• 메모리관리정책에 따른 기본할당 값
• RESULT_CACHE_MAX_SIZE
MEMORY_TARGET 사용시 : MEMORY_TARGET 의 0.25%SGA_TARGET 사용시 : SGA_TARGET 의 0.5%SHARED_POOL_SIZE 사용시 : SHARED_POOL_SIZE 의 1%
최소값 은 0, result caching disable최대값은 shared pool 크기의 75%변경시 Instance restart 필요
9/72
MV vs. Results Cache
• 유사한 기능으로 Materialized view 와 의 비교
• Materialized view• 데이터베이스 스토리지에 저장
• 데이터 변경시 mv 는 알지 못하고 수동으로 리프레시 하지 않을
시 최신의 정보를 반영하지 못함
• 서브테이블에 대한 base query 재실행 필요
• rewrite 알고리즘 적용
• Results Cache• 데이터베이스 메모리에 저장
• Shutdown 또는 result_cache 공간부족시 삭제 처리됨
• 데이터 변경시 자동 리프레시
• 동일한 SQL과 데이터가 변경되지 않을 때 재사용
10/72
Setting up Query Result Cache
매개변수 설명
result_cache_max_size 결과 캐시의 최대 크기(5 MB인 경우 '5M'으로 입력). 이 값을
0으로 설정하면 결과 캐싱은 완전히 비활성화됩니다.
result_cache_max_result 하나의 result 가 사용될 수 있는 최대 캐시 크기를
result_cache_memory 전체크기에 대한 % 로 설정.디폴트는 5%
result_cache_mode 이 매개변수를 FORCE로 설정하면 모든 쿼리 결과가 (캐시
사이즈 기준을 만족하는 한) 캐시에 저장
특정SQL 에 대해 /*+no_result_cache*/ 로 제외설정가능.디폴트는 MANUAL로, 힌트 /*+result_cache*/ 를 사용한
쿼리에 대해서만 결과가 캐시에 저장됩니다.
result_cache_remote_expiration 원격 오브젝트에 대한 쿼리 결과로 캐시된 데이터가 유효한
시간(분 단위)을 설정합니다. 디폴트 값은 0입니다.
11/72
Using the Result_Cache Hint
select /*+ result_cache */ department_id, avg(salary)
from employees
group by department_id;
SELECT /*+ NO_RESULT_CACHE */ department_id, avg(salary)
from employees
group by department_id;
result_cache_mode = MANUAL :
result_cache_mode = FORCE :
12/72
Viewing the Memory Allocation Statistics for Result Cache
SQL> set serveroutput on
execute dbms_result_cache.memory_report
execute dbms_result_cache.flush
Create the report
Flush Cache
13/72
dbms_result_cache 패키지 (Report)SQL> set serveroutput on size 999999SQL> execute dbms_result_cache.memory_reportR 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 bytesMaximum Cache Size = 2,560K bytes (2,560 blocks)Maximum Result Size = 128K bytes (128 blocks)[Memory]Total Memory = 126,736 bytes [0.041% of the Shared Pool]... Fixed Memory = 5,132 bytes [0.002% of the Shared Pool]... Dynamic Memory = 121,604 bytes [0.040% of the Shared Pool]....... Overhead = 88,836 bytes....... Cache Memory = 32K bytes (32 blocks)........... Unused Memory = 21 blocks........... Used Memory = 11 blocks............... Dependencies = 4 blocks (4 count)............... Results = 7 blocks................... SQL = 5 blocks (4 count)................... Invalid = 2 blocks (2 count)
PL/SQL procedure successfully completed.
14/72
dbms_result_cache 패키지 (flush)
• Cache 전체 삭제begin
dbms_result_cache.flush;end;
• Cache 부분 삭제begin
dbms_result_cache.invalidate('ARUP','CUSTOMERS');end;
15/72
서브쿼리 (Cache 유효성)select prod_subcategory, revenuefrom (
select /*+ result_cache */ p.prod_category,p.prod_subcategory,sum(s.amount_sold) revenue
from products p, sales swhere s.prod_id = p.prod_id and s.time_id between to_date('01-jan-1990','dd-mon-yyyy')and to_date('31-dec-2007','dd-mon-yyyy')group by rollup(p.prod_category, p.prod_subcategory)
)where prod_category = 'software/other'/
16/72
Cache-in 조건
• Cache-in 조건• 현재 쿼리의 결과가 cache 되어 있는 않을때
• 그리고 그 쿼리의 결과가 RESULT_CACHE_MAX_RESULT 보다
작을 때
• /*+result_cache*/ 힌트를 주더라도 무시되는 제약조건• Dictionary 및 temporary 테이블에 대한 쿼리
• 시퀀스의 CURRVAL / NEXTVAL 에 대한 쿼리
- 쿼리 수행 마다 결과값이 달라지는 일시적 쿼리 이기에 제외함
• current_date, current_timestamp, local_timestamp, userenv/sys_context
(with non-constant variables), sys_guid,
sysdate, sys_timestamp 등의함수호출이포함된 query• Non-deterministic PL/SQL 함수를호출하는 query
17/72
Cache-hit 조건
• Cache-hit 이란?• 실제로 실행했을 때 동일한 결과를 result cache 로 부터 얻었을때
• Cache-hit 조건• 동일한 SQL 과 동시에 동일한 parameter• 동일한 parameter 란?
• Bind 변수
• dbtimezone, sessiontimezone,userenv/sys_context
(with constant variables), uid, user 등의보다정적인함수호출결과
• NLS 등의환경 parameters
18/72
Cache-out
조건
• Cache 된 result 는 다음의 경우에 result cache 로 부터 out • Age-out. Result cache 역시 LRU cache이기때문• Invalidation. 해당 query가참조하는 object에 DML 등의변경이
일어나는경우
19/72
SQL Result Cache (딕셔너리뷰)
뷰 설명
(G)V$RESULT_CACHE_STATISTICS 메모리 사용량 등을 포함하는 다양한 설정을 확인
(G)V$RESULT_CACHE_MEMORY SQL Result Cache의 메모리 구성 을 확인
(G)V$RESULT_CACHE_OBJECTS SQL Result Cache를 구성하는 오브젝트들을 확인
(G)V$RESULT_CACHE_DEPENDENCY SQL Result Cache를 구성하는 다양한 오브젝트
간의 종속성을 확인
20/72
SQL Result Cache 초기화 : DBMS_RESULT_CACHESQL> connect / as sysdbaConnected.SQL> SET FEEDBACK 1SQL> SET NUMWIDTH 10SQL> SET LINESIZE 150SQL> SET TRIMSPOOL ONSQL> SET TAB OFFSQL> SET PAGESIZE 1000SQL> SET SERVEROUTPUT ONSQL> show parameter result_cache_mode
NAME TYPE VALUE------------------------------------ ---------------------- ----------------------result_cache_mode string MANUALSQL> show parameter memory_target
NAME TYPE VALUE------------------------------------ ---------------------- ----------------------memory_target big integer 412MSQL> 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 5SQL>
하나의 결과에 사용될 수 있는
최대 캐시 크기를 결정합니다.(%)
결과 캐시의 최대 크기
FORCE로 설정하면 모든 쿼리 결과가
캐시에 저장되고, 디폴트 MANUAL은
힌트를 사용한 쿼리에 대해서만
결과가 캐시에 저장됩니다.
21/72
SQL Result Cache 초기화 : DBMS_RESULT_CACHE
SQL> execute dbms_result_cache.flush; -- result cache를
flush
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.01SQL> alter system flush shared_pool;
System altered.
Elapsed: 00:00:00.34SQL> 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가 없음
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.05SQL>
22/72
SQL Result Cache – Plan 비교SQL> connect hr/hrConnected.SQL>SQL> explain plan for
2 select /*+ result_cache */ * from departments;
Explained.
Elapsed: 00:00:00.30SQL>SQL> set echo offSQL> select * from table(dbms_xplan.display);PLAN_TABLE_OUTPUT------------------------------------------------------------------------------------------------------Plan hash value: 4167016233
-------------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |-------------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 27 | 540 | 3 (0)| 00:00:01 || 1 | RESULT CACHE | ggq8ztnxqw8ft4ucg3art21sjm | | | | || 2 | TABLE ACCESS FULL| DEPARTMENTS | 27 | 540 | 3 (0)| 00:00:01 |-------------------------------------------------------------------------------------------------
Result Cache Information (identified by operation id):------------------------------------------------------
1 - column-count=4; dependencies=(HR.DEPARTMENTS); name="select /*+ result_cache */ * from departments"
14 rows selected.
Elapsed: 00:00:02.17SQL>
디폴트 MANUAL은 힌트를 사용한
쿼리에 대해서만 결과가 캐시에
저장됩니다.
23/72
SQL Result Cache (Inline view) – Plan 비교
SQL> connect hr/hrConnected.SQL>SQL> explain plan for
2 select department_name, emp_count3 from (select /*+ result_cache */ department_id, count(*) emp_count
from employees group by department_id) e,4 departments d5 where e.department_id = d.department_id;
Explained.
Elapsed: 00:00:00.12SQL>SQL> set echo offSQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT--------------------------------------------------------------------------------------------------------Plan hash value: 523547400
24/72
SQL Result Cache (Inline view) – Plan 비교
--------------------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time --------------------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 11 | 462 | 7 (29)| 00:00:01 | 1 | MERGE JOIN | | 11 | 462 | 7 (29)| 00:00:01 | 2 | TABLE ACCESS BY INDEX ROWID| DEPARTMENTS | 27 | 432 | 2 (0)| 00:00:01 | 3 | INDEX FULL SCAN | DEPT_ID_PK | 27 | | 1 (0)| 00:00:01 |* 4 | SORT JOIN | | 11 | 286 | 5 (40)| 00:00:01 | 5 | VIEW | | 11 | 286 | 4 (25)| 00:00:01 | 6 | | RESULT CACHE | 7n7dsf9ukwqcv7cwbupmmdntaj | | | | | 7 | HASH GROUP BY | | 11 | 33 | 4 (25)| 00:00:01 | 8 | TABLE ACCESS FULL | EMPLOYEES | 107 | 321 | 3 (0)| 00:00:01 --------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):---------------------------------------------------
4 - access("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")filter("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")
Result Cache Information (identified by operation id):------------------------------------------------------
6 - column-count=2; dependencies=(HR.EMPLOYEES); name="select /*+ result_cache */ department_id, count(*) emp_count from employees group by department_id"
26 rows selected.
Elapsed: 00:00:00.09SQL>
25/72
Test : 실제수행1
SQL> connect hr/hrConnected.SQL>SQL> select /*+ result_cache */ * from departments;
DEPARTMENT_ID DEPARTMENT_NAME MANAGER_ID LOCATION_ID------------- ------------------------------------------------------------ ---------- -----------
10 Administration 200 170020 Marketing 201 180030 Purchasing 114 170040 Human Resources 203 240050 Shipping 121 150060 IT 103 140070 Public Relations 204 270080 Sales 145 250090 Executive 100 1700100 Finance 108 1700110 Accounting 205 1700120 Treasury 1700130 Corporate Tax 1700140 Control And Credit 1700150 Shareholder Services 1700160 Benefits 1700170 Manufacturing 1700180 Construction 1700190 Contracting 1700200 Operations 1700210 IT Support 1700
26/72
Test : 실제수행2220 NOC 1700230 IT Helpdesk 1700240 Government Sales 1700250 Retail Sales 1700260 Recruiting 1700270 Payroll 1700
27 rows selected.
Elapsed: 00:00:00.05SQL>SQL> select department_name, emp_count2 from (select /*+ result_cache */ department_id, count(*) emp_count3 from employees4 group by department_id) e, departments d5 where e.department_id = d.department_id;
DEPARTMENT_NAME EMP_COUNT------------------------------------------------------------ ----------Administration 1Marketing 2Purchasing 6Human Resources 1Shipping 45IT 5Public Relations 1Sales 34Executive 3Finance 6Accounting 2
11 rows selected.
Elapsed: 00:00:00.05SQL>SQL> set echo offSQL>
처음 쿼리 돌렸을 때의 속도 입니다.
27/72
Test : 수행확인 (v$result_cache_statistics)
SQL> connect / as sysdbaConnected.SQL> col name format a55SQL> select * from v$result_cache_statistics;
ID NAME VALUE---------- ------------------------------------------------------- ----------
1 Block Size (Bytes) 10242 Block Count Maximum 10563 Block Count Current 324 Result Size Maximum (Blocks) 525 Create Count Success 26 Create Count Failure 07 Find Count 08 Invalidation Count 09 Delete Count Invalid 0
10 Delete Count Valid 0
10 rows selected.
Elapsed: 00:00:00.02SQL>
Result_Cache 등록
확인
28/72
Test결과 : 실제수행1 (재실행)SQL> connect hr/hrConnected.SQL>SQL> select /*+ result_cache */ * from departments;
DEPARTMENT_ID DEPARTMENT_NAME MANAGER_ID LOCATION_ID------------- ------------------------------------------------------------ ---------- -----------
10 Administration 200 170020 Marketing 201 180030 Purchasing 114 170040 Human Resources 203 240050 Shipping 121 150060 IT 103 140070 Public Relations 204 270080 Sales 145 250090 Executive 100 1700100 Finance 108 1700110 Accounting 205 1700120 Treasury 1700130 Corporate Tax 1700140 Control And Credit 1700150 Shareholder Services 1700160 Benefits 1700170 Manufacturing 1700180 Construction 1700190 Contracting 1700200 Operations 1700210 IT Support 1700220 NOC 1700230 IT Helpdesk 1700240 Government Sales 1700250 Retail Sales 1700260 Recruiting 1700270 Payroll 1700
27 rows selected.
Elapsed: 00:00:00.01
다시 쿼리 돌렸을 때의 속도 입니다.
29/72
Test결과 : 실제수행2 (재실행)Elapsed: 00:00:00.01SQL>SQL> select department_name, emp_count
2 from (select /*+ result_cache */ department_id, count(*) emp_count3 from employees4 group by department_id) e, departments d5 where e.department_id = d.department_id;
DEPARTMENT_NAME EMP_COUNT------------------------------------------------------------ ----------Administration 1Marketing 2Purchasing 6Human Resources 1Shipping 45IT 5Public Relations 1Sales 34Executive 3Finance 6Accounting 2
11 rows selected.
Elapsed: 00:00:00.01SQL>SQL> set echo offSQL>
다시 쿼리 돌렸을 때의 속도 입니다.
30/72
Test결과 : Result Cache 적용확인
SQL> connect / as sysdbaConnected.SQL> col name format a55SQL> select * from v$result_cache_statistics;
ID NAME VALUE---------- ------------------------------------------------------- ----------
1 Block Size (Bytes) 10242 Block Count Maximum 10563 Block Count Current 324 Result Size Maximum (Blocks) 525 Create Count Success 26 Create Count Failure 07 Find Count 28 Invalidation Count 09 Delete Count Invalid 0
10 Delete Count Valid 0
10 rows selected.
Elapsed: 00:00:00.00SQL>
cache-hit!
(v$result_cache_statistics)
31/72
<Insert Picture Here>
2. PL/SQL Function Result Cache
32/72
PL/SQL Function Cache
Select Calculate_Comp (…)…
Cached results
Select Calculate_Comp()Select
Calculate_Comp(Select Calculate_ Comp(…)…
First Query
Subsequent Queries
33/72
PL/SQL Function Cache
Cached results
Subsequent Queries
… Y:= HR.Calculate_Com p
… Y:= HR.Calculate_Com p
… Y:= HR.Calculate_Com p
… Y:= HR.Calculate_Com p
First Query
34/72
PL/SQL Function Result Cache함수가 반복 실행 되더라도 동일한 결과가 반환 될 것으로 예상될 때 적합
SQL> connect hr/hrConnected.
create or replace function get_tax_rate(
p_cust_id
customers.cust_id%type)return sales_tax_rate.tax_rate%typeresult_cacherelies_on (sales_tax_rate, customers)is
l_ret sales_tax_rate.tax_rate%type;begin
select tax_rateinto l_retfrom sales_tax_rate t, customers cwhere c.cust_id
= p_cust_idand t.state_code = c.state_code;--
simulate some time consuming--
processing by sleeping for 1 secdbms_lock.sleep
(1);return l_ret;
exceptionwhen NO_DATA_FOUND then
return NULL;when others then
raise;end;/
하부 테이블에 대한 종속관계 설정. 데이터 변경시 캐시 무효화
35/72
PL/SQL Function Result Cache
SQL> select get_tax_rate(1)
from dual;
GET_TAX_RATE(1)---------------
61 row selected.
Elapsed: 00:00:01.21
SQL> select get_tax_rate(1)
from dual;
GET_TAX_RATE(1)---------------
6
1 row selected.
Elapsed: 00:00:00.01
최초 실행 시 1.21 초
재 실행 시 0.01 초캐시에 저장된 Result 사용
36/72
PL/SQL Function Result CacheSQL> select get_tax_rate(&n) from dual;Enter value for n: 5old 1: select get_tax_rate(&n) from dualnew 1: select get_tax_rate(5) from dual
GET_TAX_RATE(5)---------------
6
1 row selected.
Elapsed: 00:00:01.18
SQL> /Enter value for n: 5old 1: select get_tax_rate(&n) from dualnew 1: select get_tax_rate(5) from dual
GET_TAX_RATE(5)---------------
6
1 row selected.
Elapsed: 00:00:00.00SQL> /
n: 5 일 때
리프레시 자동 수행됨
최초 실행 시 0.18 초
n: 5 일 때
재 실행 시 0.00 초캐시에 저장된 Result 사용
37/72
캐시 vs. 패키지 변수
• SQL Result Cache 와 PL/SQL Function Cache
• 메모리
기반으로
구현
• 데이터
베이스
인스턴스
단위로
관리
되기
때문에
서로
다른
세션에서
사용가능
• 데이터
벤경시
자동
리프레시
• 패키지
변수
• 애플리케이션은
테이블
로우
또는
함수가
아닌
변수에
접근
• 동일
세션
내에서만
사용가능
(제한적)
• 데이터
변경
시
수동으로
리프레시
수행
• 수동
리프레시
미적용시
변경이전의
데이터가
조회될
가능발생
38/72
PL/SQL Function Result Cache (Cache-in)
• PL/SQL function 의 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 내에서정의된
경우
Error 예시)LINE/COL ERROR--------
-----------------------------------------------------------------0/0 PL/SQL: Compilation unit analysis terminated1/39 PLS-00999: implementation restriction (may be temporary)
RESULT_CACHE is disallowed on subprograms with OUT or IN OUTparameters
RESULT_CACHE 절RELIES_ON 절 : dependent object 명시
39/72
Cache-hit 조건
• 동일한 함수, 동일한 parameter• parameter 란?
• function 의 parameter 를 의미
• PL/SQL 코드 내에서 ‘A’=‘A ‘ 와 같은 두 값이 parameter 로 왔을
때 동일한 parameter 로 취급되지 않는다. (bit for bit 로 동일)
40/72
TEST : PL/SQL Function Result Cache 설정 및 초기화
SQL> connect / as sysdbaConnected.SQL> SET FEEDBACK 1SQL> SET NUMWIDTH 10SQL> SET LINESIZE 150SQL> SET TRIMSPOOL ONSQL> SET TAB OFFSQL> SET PAGESIZE 1000SQL> SET SERVEROUTPUT ONSQL> show parameter result_cache_mode
NAME TYPE VALUE------------------------------------ ---------------------- -------------------------result_cache_mode string MANUALSQL> show parameter result_cache_max_size
NAME TYPE VALUE------------------------------------ ---------------------- -------------------------result_cache_max_size big integer 1056KSQL> show parameter result_cache_max_result
NAME TYPE VALUE------------------------------------ ---------------------- -------------------------result_cache_max_result integer 5SQL>
41/72
TEST : PL/SQL Function Result Cache 설정 및 초기화
SQL> execute dbms_result_cache.flush;
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.02SQL> alter system flush shared_pool;
System altered.
Elapsed: 00:00:00.67SQL> execute dbms_result_cache.memory_report;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 bytesMaximum Cache Size = 1056K bytes (1056 blocks)Maximum Result Size = 52K bytes (52 blocks)[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] –- 아직
cache된 것이 없음
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.05SQL>
42/72
TEST : PL/SQL Function Result Cache 함수생성
SQL> connect hr/hrConnected.SQL>SQL> create or replace function EMP_COUNT(dept_no number)
2 return number3 result_cache relies_on (employees) –- result cache를 지정하는 syntax4 is5 v_count number;6 begin7 select count(*) into v_count8 from employees9 where department_id = dept_no;
1011 return v_count;12 end;13 /
Function created.
Elapsed: 00:00:00.89SQL>
43/72
TEST : PL/SQL Function Result Cache 함수호출 1차
SQL> connect hr/hrConnected.SQL>SQL> select department_name, emp_count(department_id) no_of_emps
2 from departments3 where department_name = 'Accounting'4 /
DEPARTMENT_NAME NO_OF_EMPS------------------------------------------------------------ ----------Accounting 2
1 row selected.
Elapsed: 00:00:00.09SQL>
처음 Cache 에
등록하면서 걸린 시간
44/72
TEST : PL/SQL Function Result Cache 함수호출 1차 (현황파악)
SQL> SET ECHO ONSQL> SET FEEDBACK 1
SQL> SET ECHO ONSQL> SET FEEDBACK 1SQL> SET NUMWIDTH 10SQL> SET LINESIZE 150SQL> SET TRIMSPOOL ONSQL> SET TAB OFFSQL> SET PAGESIZE 1000SQL>SQL> connect / as sysdbaConnected.SQL>SQL> --- Establish the cache contentSQL> set serveroutput onSQL> execute dbms_result_cache.memory_reportR 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 bytesMaximum Cache Size = 1056K bytes (1056 blocks)Maximum Result Size = 52K bytes (52 blocks)[Memory]Total Memory = 103528 bytes [0.054% of the Shared Pool]... Fixed Memory = 5132 bytes [0.003% of the Shared Pool]... Dynamic Memory = 98396 bytes [0.051% of the Shared Pool]....... Overhead = 65628 bytes....... Cache Memory = 32K bytes (32 blocks)........... Unused Memory = 29 blocks........... Used Memory = 3 blocks............... Dependencies = 2 blocks (2 count)............... Results = 1 blocks................... PLSQL = 1 blocks (1 count)
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.06
45/72
TEST : PL/SQL Function Result Cache 함수호출 1차
SQL> connect / as sysdbaConnected.SQL>SQL> col name format a55SQL>SQL> select type, namespace,status, scan_count,name
2 from v$result_cache_objects3 /
TYPE NAMESPACE STATUS SCAN_COUNT NAME-------------------- ---------- ------------------ ---------- -----------------------Dependency Published 0 HR.EMP_COUNTDependency Published 0 HR.EMPLOYEESResult PLSQL Published 0 "HR"."EMP_COUNT"::8."EMP_COUNT"#fac892c7867b54c6 #1
3 rows selected.
Elapsed: 00:00:00.01SQL>
지금 처음 cache 되었고
아직 참조 되지 않았음
46/72
TEST : PL/SQL Function Result Cache 함수호출 1차 (v$result_cache_statistics)
SQL> connect / as sysdbaConnected.SQL>SQL> col name format a55SQL>SQL> select * from v$result_cache_statistics;
ID NAME VALUE---------- ------------------------------------------------------- ----------
1 Block Size (Bytes) 10242 Block Count Maximum 10563 Block Count Current 324 Result Size Maximum (Blocks) 525 Create Count Success 1 –-
Cache-in!6 Create Count Failure 07 Find Count 08 Invalidation Count 09 Delete Count Invalid 0
10 Delete Count Valid 0
10 rows selected.
Elapsed: 00:00:00.00SQL>
Cache 가 1개 생성 된
것 을 확인
47/72
TEST 결과 : PL/SQL Function Result Cache 함수호출 2차
SQL> connect hr/hrConnected.SQL>SQL> select department_name, emp_count(department_id) no_of_emps
2 from departments3 where department_name = 'Accounting'4 /
DEPARTMENT_NAME NO_OF_EMPS------------------------------------------------------------ ----------Accounting 2
1 row selected.
Elapsed: 00:00:00.00SQL> 등록된 Cache 사용으로
속도가 감소 되었다.Elapsed: 00:00:00.09
48/72
Test결과 : PL/SQL Function Result Cache 함수호출 2차
SQL> connect / as sysdbaConnected.SQL>SQL> col name format a55SQL>SQL> select * from v$result_cache_statistics;
ID NAME VALUE---------- ------------------------------------------------------- ----------
1 Block Size (Bytes) 10242 Block Count Maximum 10563 Block Count Current 324 Result Size Maximum (Blocks) 525 Create Count Success 16 Create Count Failure 07 Find Count 1 –-
Cache-hit!8 Invalidation Count 09 Delete Count Invalid 0
10 Delete Count Valid 0
10 rows selected.
Elapsed: 00:00:00.00
Cache 가 1개 사용으로
Cache-hit 성공
49/72
Test결과 : PL/SQL Function Result Cache 함수호출 2차
Elapsed: 00:00:00.00SQL>SQL> connect / as sysdbaConnected.SQL>SQL> col name format a55SQL>SQL> select type, namespace,status, scan_count,name
2 from v$result_cache_objects3 /
TYPE NAMESPACE STATUS SCAN_COUNT NAME-------------------- ---------- ------------------ ---------- ----------------------- --------------------------------Dependency Published 0 HR.EMP_COUNTDependency Published 0 HR.EMPLOYEES
Result PLSQL Published 1 –- cache-hit!"HR"."EMP_COUNT"::8."EMP_COUNT"#fac892c7867b54c6 #1
3 rows selected.
Elapsed: 00:00:00.01SQL>
50/72
<Insert Picture Here>
3. Client Query Result Cache
51/72
OCI Consistent Client Cache 서버와 클라이언트 사이의 cache fusion과 같은 효과
• Query 결과를 클라이언트에 캐쉬
• 읽기 위주 테이블에 대한 성능 향상• Network round trip 제거에 따른 응답 속도의 향상
• 서버의 CPU 사용률 절약
• 서버와 클라이언트 사이의 데이터 일관성• Result set이 변경되면 캐쉬는 능동적으로 갱신됨
Application Server
Database
Consistent Caching
52/72
Client Query Result Cache 설정
• 클라이언트가 대역폭이 제한된 네크웍 링크를 통해 데이터를 조회
해야 하는 경우
• 데이터베이스 캐시로 부터 전달받은 결과를 Client 캐시로 저장 후
사용하고자 할때
• 이 기능을 사용하려면 초기화 매개변수를 아래와 같이 수정해 주기만
하면 됩니다:
• 위 구문은 클라이언트 캐시를 1GB로 설정하고 있습니다. 이 값은 모든
클라이언트의 캐시 사이즈를 합산한 결과로 정의됩니다. (이 매개변수는 정적으로 정의되므로 데이터베이스를 재시작해 주어야
합니다.) 클라이언트 쪽에서는 SQLNET.ORA 파일의 매개변수를
수정하여 캐시를 설정합니다.
CLIENT_RESULT_CACHE_SIZE = 1G
53/72
SQL Result Cache 파라미터
매개변수 설명
OCI_RESULT_CACHE_MAX_SIZE 특정
클라이언트
내부의
캐시
사이즈를
설정합니다.
OCI_RESULT_CACHE_MAX_RSET_SIZE 결과
셋의
최대
크기를
설정합니다.
OCI_RESULT_CACHE_MAX_RSET_ROWS 결과
셋의
최대
로우
수를
설정합니다.
Using Client configuration file (sqlnet.ora)
54/72
OCI statement caching
:
enableYou can enable client-side query caching by:JDBC OCI, OCCI, ODP.Net, PHP, ODBC• Server
• CLIENT_RESULT_CACHE_SIZE (default 0, cache disabled)•
하나의클라이언트프로세스가가질수있는 result cache의최대크기를지정한다. 0으로지정하면클라이언트단의 result caching이 disable된다. Sqlnet.ora
파라미터인 OCI_RESULT_CACHE_MAX_SIZE를통해 override할수있다.
• CLIENT_RESULT_CACHE_LAG (optional, 3000ms default)•
클라이언트 result cache가서버단의변경에대해가질수있는 lag의최대값이다. 디폴트는 3 초이다. OCI 캐쉬의일관성은기본적으로 OCIStmtExecute() call에의한
check를통해이루어진다. 만일서버호출이한동안없다면? 그렇다하더라도이
파라미터에의해주기적으로 sync를맞추게되는것이다.
• Client (set in sqlnet.ora)• OCI_RESULT_CACHE_MAX_SIZE (optional)• OCI_RESULT_CACHE_MAX_RSET_SIZE (optional)• OCI_RESULT_CACHE_MAX_RSET_ROWS (optional)
• Executing the CREATE TABLE or ALTER TABLE statements• Embedding a SQL hint - /*+ result_cache */
55/72
OCI Consistent Client Cache Caveats
• Some restrictions• views• VPD• DBlinks
• Monitor usage• client_result_cache_stats$
• Control the “lag”• client_result_cache_lag (default 3000ms)
56/72
Using Client-side Query Cache Example
• init.ora example:
• ALTER TABLE statement:
• SQL hint:
CLIENT_RESULT_CACHE_SIZE –- this to accommodate the -- total size of all queries that my be cached on the -- client
ALTER TABLE products RESULT_CACHE;
SELECT /*+ result_cache */ product_name FROM productsORDER BY product_name;
57/72
Client –side Cache-hit•
Client란?
• JDBC-OCI, ODP.Net, OCCI, Pro*C/C++, Pro*COBOL, ODBC 등의 OCI 클라이언트를
의미한다.
• OCI Statement Caching
• Client-side SQL query result cache를
사용하기
위해서는
반드시
OCI
statement caching이
enable되어
있어야
한다.
• CLIENT_RESULT_CACHE_STATS$
•
클라이언트
단의
result cache에
대한
통계를
보여주는
view이다.
• OCI 클라이언트가
주기적으로
이
view를
update하게
된다. 내용은
V$RESULT_CACHE_STATISTICS와
거의
흡사하다.
• Client-side query result cache 사용 예
• $ORACLE_HOME/rdbms/demo/cdemoqc.sql
및
$ORACLE_HOME/rdbms/demo/cdemoqc.c
에
예제가
주어진다.
58/72
Client Query Result Cache 적용 가능 환경 및 장점
• 적용 가능 환경• OCI8 드라이버를 이용하는 데이터베이스 클라이언트 스택(C, C++, JDBC-OCI 등)
• 적용시 이점• 애플리케이션 개발자들이 SQL Result Cache를 일관성 있게 구현해야 할
필요성을 제거합니다
• 비용 면에서 보다 저렴한 클라이언트 메모리를 활용하여 애플리케이션
워킹 셋을 로컬에 저장함으로써, 서버-사이드 쿼리 캐싱을 클라이언트
메모리로 확장합니다. • 서버 리소스 절감을 통해 서버 확장성을 개선합니다.• 메모리 관리, 결과 셋의 동시 접근 등 투명한 캐시 관리 기능을 제공합니다. • 서버의 데이터가 변경되는 경우에도 투명하고 일관성 있는 방식으로
캐시를 유지합니다. • RAC 환경에서의 일관성을 보장합니다.
59/72
예제 : Client Query Result Cache (OCI8)
import java.sql.Statement;public class CacheTest
{private String jdbcURL
= "jdbc:oracle:oci8:@PRONE3";private Connection conn
= null;public CacheTest( ) throws ClassNotFoundException
{Class.forName("oracle.jdbc.driver.OracleDriver");
} public static void main(String[] args) throws ClassNotFoundException, SQLException
{CacheTest
check = new CacheTest();check.dbconnect();check.doSomething();
}public void dbconnect() throws SQLException
{System.out.println("Connecting
with URL="+jdbcURL+" as arup/arup");try {
conn
= DriverManager.getConnection( jdbcURL, "arup" , "arup");System.out.println("Connected
to Database");} catch (SQLException
sqlEx) {System.out.println(" Error connecting to database : " + sqlEx.toString());
}
60/72
예제 : Client Query Result Cache (OCI8)
}public void doSomething() throws SQLException
{Statement stmt = null;ResultSet
rset
= null;try {stmt = conn.createStatement();System.out.println("Created
Statement object");rset
= stmt.executeQuery("select
/*+ result_cache */ * from customers");System.out.println("Retrieved
ResultSet
object");if(rset.next())
System.out.println("Result:"+rset.getString(1));} catch (SQLException
sqlEx) {} finally {
try {System.out.println("Closing
Statment
& ResultSet
Objects");if (rset
!= null) rset.close();if (stmt != null) stmt.close();if (conn
!= null) {System.out.println("Disconnecting...");conn.close();System.out.println("Disconnected
from Database");}
} catch (Exception e) { }}
}}
61/72
예제 : Client Query Result Cache (OCI8)
위의코드를 CacheTest.java
파일에저장하고컴파일을수행합니다:
$ORACLE_HOME/jdk/bin/javac
CacheTest.java
이제컴파일된클래스를실행합니다: $ORACLE_HOME/jdk/bin/java -classpath
.:$ORACLE_HOME/jdbc/lib/ojdbc5.jar CacheTestConnecting with URL=jdbc:oracle:oci8:@PRONE3 as arup/arupConnected to DatabaseCreated Statement objectRetrieved ResultSet
objectResult :MClosing Statment
& ResultSet
ObjectsDisconnecting...Disconnected from Database
실행작업을몇차례반복합니다. 실행이여러차례반복되면서, 아래의다이내믹뷰를통해
클라이언트캐시에결과값이저장되었음을확인할수있습니다. select * from client_result_cache_stats$/select * from v$client_result_cache_stats/
62/72
Client Query Result Cache
Client-Side Query Result Cache는 일반적으로
자주
변경되지
않는
정적
테이블에서
유용하게
활용됩니다. (물론
데이터가
변경된다면
캐시는
다시
리프레시
됩니다.)
Client-side Query Result Cache는 캐시가
서버가
아닌
클라이언트에
저장된다는
점에서
SQL Result Cache와
차이를
갖습니다. 따라서
클라이언트가
데이터를
얻기
위해
서버에
직접
접촉할
필요가
없으며, 그
결과로
네트워크
대역폭과
서버
CPU를
동시에
절감할
수
있습니다.
63/72
<Insert Picture Here>
4. Database Resident Connection Pooling
64/72
Database Resident Connection Pooling
1: M 의 관계 : 웹
기반
시스템에서과
같은
환경에서
형성.
많은
수의
동시
연결
관리필요
전통적인
클라이언트-사이드
/ 미들-티어
커넥션
풀링
의
문제점:
• 각각의
풀은
단일
미들-티어
노드로
제한
• 풀의
크기가
증가하는
경우
데이터베이스
서버의
메모리
리소스를
소진
• 워크로드의
분산이
효율적으로
수행되기
어려움
65/72
Database Resident Connection PoolingOracle Database 11g에는
Database Resident Connection Pool(DRCP)이라는
이름의
서버-사이드
풀이
새로
추가되었습니다.
DRCP는
C, C++, PHP 등
OCI 드라이버를
사용하는
모든
데이터베이스
클라이언트에서
사용
가능합니다.
tnsnames.ora
PRONE3_POOL =(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = prolin3.proligence.com)(PORT = 1521))(CONNECT_DATA =(SERVER = POOLED)(SID = PRONE3)
))
execute dbms_connection_pool.start_pool;
66/72
Database Resident Connection Pool
No Connection Pooling 11g Database Resident Connection Pooling
Note: will require a new PHP driver to be released post 11.1
67/72
Database Resident Connection Pooling
이제
데이터베이스
연결을
위한
connect 문자열을
변경합니다. Client-Side Result Cache 섹션의
예제
코드를
다시
활용해
보겠습니다:
이것으로
모든
작업이
완료되었습니다. 이제
애플리케이션은
서버가
아닌
풀로
연결됩니다.
씬
클라이언트와
표준
JDBC 연결
문자열을
사용하는
경우라면
POOLED 구문을
사용할
수
있습니다:
위의
구문을
통해
오라클에
기본
설정된
디폴트
풀이
시작됩니다.
DBMS_CONNECTION_POOL 패키지에
포함된
CONFIGURE_POOL 프로시저를
사용하여
풀의
설정을
변경할
수
있습니다.
private String jdbcURL
= "jdbc:oracle:oci8:@PRONE3_POOL";
prolin3. proligence.com:1521/PRONE3:POOLED
68/72
Connection Pooling (Parameter)
매개변수 설 명
POOL_NAME 풀의 이름 (작은 따옴표 기호('')를 사용합니다)
MINSIZE 풀에 유지되는 세션에 최소 수
MAXSIZE 풀에서 허용되는 최대 세션 수
INCRSIZE 폴링(polling) 대상 서버가 접근 불가능한 경우, 이
매개변수에 설정된 값만큼 서버의 수를 증가시킵니다.
SESSION_CACHED_CURSORS 'session cached cursor'를 활성화합니다.
INACTIVITY_TIMEOUT 지정된 시간만큼 세션이 유휴 상태를 유지하면 세션 연결이
해제됩니다.
MAX_THINK_TIME 클라이언트가 풀로부터 서버를 가져온 뒤, 이 매개변수에
설정된 시간 안에 SQL 구문을 실행하지 않으면 서버 연결이
해제됩니다.
MAX_USE_SESSION 연결을 풀에서 가져올 수 있는 최대 횟수
MAX_LIFETIME_SESSION 세션의 최대 지속 시간
69/72
<Insert Picture Here>
5. Adaptive Cursor Sharing• 바인딩 변수 처리방안
70/72
Adaptive Cursor Sharing과거바인트변수의문제점 => 정적인실행계획
바인드변수를사용하는 SQL 이처음실행될때의 Plan 으로고정된다는문제점발생
극복하기위해Oracle Database 11g New Features 로 Adaptive Cursor Sharing 기능
제공함으로써바인드변수의변경에따라개발자나관리자의별도의설정없이오라클
데이터베이스 11g 의자체기능으로변경된실행계획을적용받게됩니다.
EXACT : (default) 완전히
일치하는
SQL 에
대해서만
커서공유
(바인드변수
사용)
SIMILAR : SQL 의
리터럴값이
다른
값으로
대체
되더라도SQL 의미
변화없고, 실행계획
변화없고, Oracle 이
자동으로
생성한
바인드변수로
대체
가능
FORCE : SQL 문장에
사용된
리터럴값이
다른
값으로
대체
될때SQL 의미
변화없다면, Oracle 이
자동으로
생성한
바인드변수로
대체
가능
CURSOR_SHARING =‘EXACT’
71/72
Adaptive Cursor SharingOracle database 11g 에서바인딩변수를사용하기위해서는별도의설정이필요하지않습니다.테이블의통계정보가
생성되고컬럼에대한히스토그램이생성되어있으면됩니다.
따라서오라클11g 자체기능으로서
기본적으로활성화됩니다.SQL> show userUSER is "SCOTT"SQL> variable v_deptno numberSQL> exec :v_deptno := 10SQL> alter system flush shared_pool ;System altered.SQL>SQL> select /*TAGGING*/ count(*), max(sal)2 from emp
3 where deptno = :v_deptno;COUNT(*) MAX(SAL)
---------- ----------3 5000
SQL> select * from table(dbms_xplan.display_cursor);PLAN_TABLE_OUTPUT------------------------------------------------------------------------------------------SQL_ID 73mcauwj27cdv, child number 2-------select /*TAGGING*/ count(*), max(sal) from emp where deptno = :v_deptnoPlan hash value: 3489981422---------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |---------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | | | 2 (100)| || 1 | SORT AGGREGATE | | 1 | 7 | | || 2 | TABLE ACCESS BY INDEX ROWID| EMP | 3 | 21 | 2 (0)| 00:00:01 ||* 3 | INDEX RANGE SCAN | EMP_IX | 3 | | 1 (0)| 00:00:01 |
72/72