본문 바로가기
스터디/오라클 성능고도화 원리와 해법1

06.I/O 효율화 원리 - 07. Result 캐시

by 취미툰 2020. 2. 15.
반응형

버퍼 캐시에 위치하지 않고 Shared Pool에 위치합니다.
오라클은 11g부터 한번 수행한 쿼리 또는 PL/SQL 함수의 결과값을 Result 캐시에 저장 해두능 기능을 제공합니다.
1.DML이 거의 발생하지 않는 테이블을 참조하면서
2.반복 수행요청이 많은 쿼리에 이 기능을 사용하면 I/O 발생량을 현격히 감소시킬 수 있습니다.
Result 캐시 메모리는 다음 두 가지 캐시 영역으로 구성됩니다.
SQL Query Result 캐시 : SQL 쿼리 결과를 저장
PL/SQL 함수 Result 캐시 : PL/SQL 함수 결과값을 저장
아래는 Result 캐시를 위해 추가된 파라미터들입니다.

result_cache_max_size를 관리자가 직접 지정하지 않으면 ,아래 규칙에 따라 오라클이 자동으로 값을 할당합니다.
- SGA와 PGA를 통합 관리하는 11g방식으로 SGA메모리를 관리하면, memory_target으로 설정된 값의 0.25%를 result캐시를 위해 사용합니다.
- sga_target 파라미터를 사용하는 10g 방식으로 SGA 메모리를 관리하면, 그 값의 0.5%를 result캐시를 위해 사용합니다.
- 과거처럼 shared_pool_Size를 수동으로 설정하면 그 값의 1%를 result캐시를 위해 사용합니다.
- 어떤 방식을 사용하든 result 캐시가 사용할 수 있는 최대 크기는 Shared Pool의 75%을 넘지 않도록 오라클이 관리합니다.
Result 캐시는 SGA의 shared pool에 저장됩니다. SGA영역이므로 모든 세션에서 공유할 수 있고, 인스턴스를 재기동하면 당연히 초기화 됩니다.
공유영역에 위치하므로 래치가 필요한데, 11g에서 아래 두 가지 래치가 추가되었습니다.
Result Cache :Latch
Result Cache : SO Latch
Manual 모드에서 /*+ RESULT_CACHE */ 힌트를 사용해서 사용할 수 있습니다.
이때 Result 캐시 메모리를 먼저 찾아보고 캐싱돼 있다면 그것을 가져다가 결과 집합을 리턴합니다. 캐시에서 찾지 못 할때만 쿼리를 수행해 결과를 리턴하고 result 캐시에 저장합니다. 즉, result 캐시에서 결과 집합을 찾았을 때는 실제 쿼리를 수행하지 않기 때문에 블록 I/O가 전혀 발생하지 않습니다.
단, 아래 경우에는 쿼리 결과집합을 캐싱하지 못합니다.
- Dictionary 오브젝트를 참조할 때
- Temporary 테이블을 참조할 때
- 시퀀스로부터 CURRVAL, NEXTVAL Pseudo 컬럼을 호출할 때
- 쿼리에서 아래 SQL 함수를 사용할 때
CURRENT_DATE
CURRENT_TIMESTAMP
LOCAL_TIMESTAMP
SYS_CONTEXT( with non-constant variables)
SYS_GUID
SYSDATE
SYSTIMESTAMP
USERENV

바인드변수를 사용할때는 각 바인드 변수 값에 따라 개별적으로 캐싱이 이루어집니다.
다른 바인드 변수지만 같은 쿼리일때는 따로 캐싱이 이루어진다는 것입니다.
따라서 변수 값의 종류가 매우 다양하고 수행 빈도가 높은 쿼리를 result 캐시에 등록하는 것은 삼가야 합니다.

오라클은 캐싱된 쿼리가 참조하는 테이블에 변경이 발생하면 (현재 발생한 DML이 캐싱된 결과 집합에 영향을 미치지 않더라도) 해당 캐시 엔트리를 무효화시킴으로써 쿼리 정합성을 보장합니다.
파티션테이블에 DML이 발생할 때도, 변경이 발생한 파티션과 무관한 파티션을 참조하는 쿼리 결과집합까지 무효화시킵니다. 즉, 2월 파티션에 DML이 발생하면 1월 파티션을 참조하는 쿼리의 캐시까지 무효화 됩니다.
함수 result 캐시도 함수에서 참조하는 테이블에 변경이 있으면 무효화됩니다.
따라서 DML이 자주 발생하는 테이블을 참조하는 쿼리나 함수를 캐싱하도록 하는 것은 시스템 부하를 오히려 가중시킬 수 있습니다. DML이 발생할 때마다 캐시를 관리하는 비용이 추가되고 그 과정에서 래치 경합도 많이 발생하기 때문입니다. 그리고 result_cache 힌트를 사용한 쿼리를 수행할 때마다 result 캐시를 탐색하는 비용이 추가로 발생하기때문에 조심해야 합니다.
여러 개 블록을 서로 연결해 최종 결과 집합을 완성하는 복잡한 형태의 쿼리에서 특정 쿼리 블록만 캐싱할 수 있으면 result 캐시 기능은 매우 높아질 수 있습니다.오라클은 그 기능을 제공하고 있습니다.
-from (select /*+RESULT_CACHE *? ~ ) 인라인 뷰 사용 가능
-with xxxx
as (select /*+ RESULT_CACHE */ ~~) with 구문 사용 가능
- select ~~~
union all
(select /*+RESULT_CAHCE */ ~) union all 절 사용 가능
- select ~ where id = (select /*+RESULT_CACHE */ ~) where 절 사용 가능

지금까지 설명한 기능은 SGA에 결과 집합을 저장하는 서버 측 result 캐시 기능이고 클라이언트 메모리에 결과 집합을 저장하는 클라이언트 측 result 캐시 기능도 11g에서 함께 제공됩니다.



반응형

댓글