문서의 선택한 두 판 사이의 차이를 보여줍니다.
다음 판 | 이전 판 | ||
study:oracle:datadb:4week_2:chap8 [2010/05/26 17:02] zummaz 새로 만듦 |
study:oracle:datadb:4week_2:chap8 [2010/05/27 14:46] (현재) zummaz |
||
---|---|---|---|
줄 1: | 줄 1: | ||
====3.3.8. 기타 ==== | ====3.3.8. 기타 ==== | ||
- | 힌트지금까지 적용 목적별 분류하여 소개한 힌트에서 누락한 10여종 힌트를 여기서 소개하고자 한다. | + | * 기타 |
===APPEND=== | ===APPEND=== | ||
- | 데이터를 입력하는 INSERT문에서 사용하는 힌트이다. | + | *데이터를 입력하는 INSERT문에서 사용하는 힌트이다. |
+ | *데이터 입력작업을 | ||
+ | *한가지 유의할 점은 반드시 | ||
- | 예) INSERT /*+ APPEND */ INTO TAB2 | + | |
SELECT * | SELECT * | ||
FROM TAB1 | FROM TAB1 | ||
WHERE COL1 >= ' | WHERE COL1 >= ' | ||
- | NOAPPEND힌트는 INSERT문을 처리할때 ' | + | \\ |
+ | *NOAPPEND힌트는 INSERT문을 처리할때 ' | ||
===CACHE=== | ===CACHE=== | ||
- | 전체 테이블 스캔방식으로 읽혀진 블록을 데이터베이스의 버퍼캐쉬를 관리하는 LRU 리스트의 최근 사용위치 (Most Recent Used End)에 머물도록 하여 계속해서 메모리 내에 머물 수 있도록 하는 힌트이다 | + | *전체 테이블 스캔방식으로 읽혀진 블록을 데이터베이스의 버퍼캐쉬를 관리하는 |
- | 크키가 작은 테이블에 유용하게 사용될수 있다. 이 힌트를 사용하면 옵티마이져는 테이블에 이미 정의되었던 기본 캐쉬(Default Caching)정의를 무효화한다. | + | *크키가 작은 테이블에 유용하게 사용될수 있다. 이 힌트를 사용하면 옵티마이져는 테이블에 이미 정의되었던 |
- | 예) SELECT /*+ FULL(t) CACHE(t) */ last_name | + | |
FROM tech_spec t; | FROM tech_spec t; | ||
===NOCAHCE=== | ===NOCAHCE=== | ||
- | 전체테이블 스캔 방식으로 읽혀진 블록을 데이터베이스 버퍼 캐쉬의 LRU리스트의 끝에 위치하도록 유도함으로써 메모리 내에서 우선적으로 제거되도록 하는 힌트이다. 이것은 데이터베이스버퍼 캐쉬에서 옵티마이져가 블록을 관리하는 일반적인 방법이기도 하다. | + | *전체테이블 스캔 방식으로 읽혀진 블록을 데이터베이스 버퍼 캐쉬의 LRU리스트의 끝에 위치하도록 유도함으로써 메모리 내에서 우선적으로 제거되도록 하는 힌트이다. |
+ | *이것은 데이터베이스버퍼 캐쉬에서 옵티마이져가 블록을 관리하는 일반적인 방법이기도 하다. | ||
예) SELECT /*+ FULL(m) NOCACHE(m) */ member_name | 예) SELECT /*+ FULL(m) NOCACHE(m) */ member_name | ||
FROM member m; | FROM member m; | ||
===CARDINALITY=== | ===CARDINALITY=== | ||
- | 옵티마이져에게 해당 쿼리 전체나 일부 구성에 대한 카디널러티 예상 값을 제시하여 실행계획 수립에 참조하도록 하는 힌트이다. 힌트에 테이블을 지정하지 않으면 이때의 카디널러티는 전체 쿼리를 수행한 결과로 얻어진 총 건수로 간주한다. | + | *옵티마이져에게 |
+ | * 힌트에 테이블을 지정하지 않으면 이때의 카디널러티는 전체 쿼리를 수행한 결과로 얻어진 총 건수로 간주한다. | ||
+ | * 실행계획의 공유 비율을 높일수 있음 | ||
+ | * CURSOR_SHARING 파라미터 | ||
+ | - EXACT : 리터럴 값을 바인드 변수로 변경하지 않고 있는 그대로 파싱 | ||
+ | - FORCE OR SIMILAR : SQL조건에 상주값을 지정해도 옵티마이져는 변수로 인정하여 실행계획 수립 | ||
+ | |||
예) SELECT /*+ CARDINALITY( s 9999 ) */ ... | 예) SELECT /*+ CARDINALITY( s 9999 ) */ ... | ||
줄 29: | 줄 40: | ||
WHERE s.sales_date >= ' | WHERE s.sales_date >= ' | ||
AND p.prod_id LIKE ' | AND p.prod_id LIKE ' | ||
+ | |||
===CURSOR_SHARING_EXACT=== | ===CURSOR_SHARING_EXACT=== | ||
- | 만약 | + | * CURSOR_SHARING 초기화 파라메터가 ' |
+ | * FORCE와 SIMILAR를 지정하면 SQL조건절에 상수값을 지정했다라도 옵티마이져는 변수로 인정하여 실행계획을 수립하므로 실행계획의 공유비율을 높일 수 있다. | ||
+ | * 또한 경우에 따라서 'ALTER SESSION ...' | ||
예) SELECT /*+ CURSOR_SHARING_EXACT */ * | 예) SELECT /*+ CURSOR_SHARING_EXACT */ * | ||
줄 37: | 줄 51: | ||
| | ||
===DRIVING_SITE=== | ===DRIVING_SITE=== | ||
- | 원격(Remote)테이블과 조인(분산쿼리)을 할 때 쿼리가 수행될 사이트를 지정하여 분산쿼리를 최적화하는데 적용하는 힌트이다. | + | * **원격(Remote)테이블과 조인(분산쿼리)**을 할 때 쿼리가 수행될 사이트를 지정하여 분산쿼리를 최적화하는데 적용하는 힌트이다. |
- | 예) SELECT /*+ DRIVING_SITE(b) */ | + | |
FROM cust a, order@ord_svr b | FROM cust a, order@ord_svr b | ||
WHERE a.join_date >= ' | WHERE a.join_date >= ' | ||
줄 45: | 줄 59: | ||
===DYNAMIC_SAMPLING=== | ===DYNAMIC_SAMPLING=== | ||
- | 우리가 통계정보를 생성해두지 않았더라도 언제나 비용기준으로 작동할수 있게 하기위한 동적 표본화(Dynamic sampling)는 옵티마이져를 설명하면서 소개 | + | *우리가 통계정보를 생성해두지 않았더라도 언제나 |
- | 샘플링 레벨은 0~10 사이로 줄수 있으며, 값이 클수록 더욱 정확한 통계정보를 수집하게 된다. 이 힌트는 바로 이 기능을 단위 SQL에 적용할수 있기 위해 탄생되었다. | + | * 이 기능은 통계정보를 가지고 있지않거나, |
+ | | ||
- | 예) SELECT /*+ DYNAMIC_SAMPLING(e 1) */ ..... | + | |
FROM EMP | FROM EMP | ||
WHERE ENAME = ' | WHERE ENAME = ' | ||
- | 어떤 테이블에 대한 카디널러티 통계가 있을 때 만약 테이블 하나만 액세스하는 쿼리에 조건절이 없는 상태에서 이 힌트를 사용하면 옵티마이져는 현존하는 통계정보를 선택하고 이 힌트를 무시한다. | ||
- | 예) SELECT /*+ DYNAMIC_SAMPLING(e 1) */ count(*) | + | *어떤 테이블에 대한 카디널러티 통계가 있을 때 만약 테이블 하나만 액세스하는 쿼리에 조건절이 없는 상태에서 이 힌트를 사용하면 옵티마이져는 현존하는 통계정보를 선택하고 이 힌트를 무시한다. |
+ | |||
+ | 예) SELECT /*+ DYNAMIC_SAMPLING(e 1) */ count(*) | ||
FROM employees e; | FROM employees e; | ||
- | | + | |
+ | *반대로, 이 상황에서 조건절이 존재하면 옵티마이져는 현존하는 카디널리티 통계를 이용하여 조건문의 선택도를 추정함으로써 이 힌트를 적용하게 된다. | ||
===PUSH_PRED=== | ===PUSH_PRED=== | ||
- | 뷰나 인라인뷰의 외부에 있는 조인 조건을 뷰 쿼리 내로 삽입하도록 하는 힌트이다. | + | * **뷰나 인라인뷰의 외부에 있는 조인 조건을 뷰 쿼리 내로 삽입**하도록 하는 힌트이다. |
+ | *인라인뷰가 수행된 결과와 조인을 하는 것이 아니라 직접 조인을 한것처럼 외부의 조인조건에 의해 조인을 수행한 후 체크 기능이 수행된다. | ||
- | 예) SELECT /* NO_MERGE(v) PUSH_PRED(v) */ | + | |
- | | + | |
( SELECT carrier_name, | ( SELECT carrier_name, | ||
FROM member_carrier | FROM member_carrier | ||
줄 67: | 줄 85: | ||
WHERE m.member_id = v.member_id(+) | WHERE m.member_id = v.member_id(+) | ||
AND m.member_type= | AND m.member_type= | ||
+ | |||
===NO_PUSH_PRED=== | ===NO_PUSH_PRED=== | ||
- | 뷰나 인라인뷰의 외부에 있는 조인조건을 뷰 쿼리 내로 삽입하지 않도록 하는 힌트이다. | + | *뷰나 인라인뷰의 외부에 있는 조인조건을 뷰 쿼리 내로 삽입하지 않도록 하는 힌트이다. |
- | 아래 SQL은 인라인뷰가 먼저 수행한 결과와 조인이 수행된다. | + | *아래 SQL은 인라인뷰가 먼저 수행한 결과와 조인이 수행된다. |
- | 예) SELECT /* NO_MERGE(v) NO_PUSH_PRED(v) */ | + | |
FROM employees e, | FROM employees e, | ||
( SELECT manager_id | ( SELECT manager_id | ||
줄 77: | 줄 96: | ||
WHERE e.manager_id = v.manager_id(+) | WHERE e.manager_id = v.manager_id(+) | ||
AND e.employee_id = 100'; | AND e.employee_id = 100'; | ||
+ | |||
===PUSH_SUBQ=== | ===PUSH_SUBQ=== | ||
- | 이 힌트는 머지되지 않는 서브쿼리를 최대한 먼저 수행할 수 있도록 실행계획을 수립하기를 요구한다. 머지가 된 서브쿼리는 먼저 수행되고 그 결과를 메인쿼리의 처리범위를 줄이는 ' | + | *이 힌트는 |
- | 예를 들어 어떤 쿼리가 선택한 결합 인덱스에서 중간에 있는 컬럼에 조건이 부여되지 않았을때 ' | + | *머지가 된 서브쿼리는 |
+ | *예를 들어 어떤 쿼리가 선택한 결합 인덱스에서 중간에 있는 컬럼에 조건이 부여되지 않았을때 ' | ||
- | 예) SELECT /*+ PUSH_SUBQ(@qb) */ | + | |
FROM sales | FROM sales | ||
WHERE item = :b1 | WHERE item = :b1 | ||
줄 88: | 줄 109: | ||
WHERE code_type = ' | WHERE code_type = ' | ||
AND saldate between :b2 and :b3; | AND saldate between :b2 and :b3; | ||
- | 그러나 그 서브쿼리가 원격 테이블이거나 Sort Merge조인의 일부로써 수행될 때는 이 힌트는 아무런 역활도 하지 못한다. | + | |
- | NO_PUSH_SUBQ 힌트는 옵티마이져가 머지되지 않는 서브쿼리르 제일 나중에 수행되도록한다. 만약 이러한 서브쿼리가 처리범위를 거의 줄여주지 못하거나 상대적으로 부담이 된다면 가능한 가장 마지막에 처리하는것이 유리한다. | + | \\ |
- | 다시 말해서 다른 조건들이 최대한 적용되어 가장 많이 줄여진 다음에 수행되는것이 유리하다. | + | *그러나 그 서브쿼리가 원격 테이블이거나 Sort Merge조인의 일부로써 수행될 때는 이 힌트는 아무런 역활도 하지 못한다. |
+ | |||
+ | *NO_PUSH_SUBQ 힌트는 옵티마이져가 머지되지 않는 서브쿼리르 제일 나중에 수행되도록한다. 만약 이러한 서브쿼리가 처리범위를 거의 줄여주지 못하거나 상대적으로 부담이 된다면 가능한 가장 마지막에 처리하는것이 유리한다. | ||
+ | *다시 말해서 다른 조건들이 최대한 적용되어 가장 많이 줄여진 다음에 수행되는것이 유리하다. | ||
===QB_NAME=== | ===QB_NAME=== | ||
- | 쿼리 블록에 이름을 부여하여 해당 쿼리 블록 외부의 다른 힌트에서 지정한 쿼리블록을 참조할 수 있도록 하는 힌트이다. | + | *쿼리 블록에 이름을 부여하여 해당 쿼리 블록 외부의 다른 힌트에서 지정한 쿼리블록을 참조할 수 있도록 하는 힌트이다. |
+ | *Query Block에 명시적으로 이름을 부여하는 역할을 한다. 주로 Inline View나 Subquery 등에 이름을 붙여서 실행 계획의 가독성을 높이는 용도로 사용된다. | ||
+ | * 명명하지 않은 쿼리 블록의 경우 옵티마이져가 자동으로 부여(PLAN_TABLE에서 확인) | ||
+ | * 참고 : http:// | ||
- | 예) SELECT /*+ UNNEST(@qb) */........ | + | |
FROM emp e | FROM emp e | ||
WHERE e.deptno IN (SELECT /*+ QB_NAME(qb) */ d.deptno | WHERE e.deptno IN (SELECT /*+ QB_NAME(qb) */ d.deptno | ||
FROM dept d | FROM dept d | ||
WHERE d.loc = ' | WHERE d.loc = ' | ||
- | 쿼리 블록에 대한 명칭은 전체 쿼리 내에 유일하게 부여되어야 하며, 동일한 쿼리블록은 다른 이름으로 여러 힌트에서 반복 사용될 수 없다. 이 힌트를 사용하면서 명명하지 않는 쿼리블록은 옵티마이져가 쿼리 블록명을 자동 생성하며, | + | |
+ | \\ | ||
+ | *쿼리 블록에 대한 명칭은 전체 쿼리 내에 유일하게 부여되어야 하며, 동일한 쿼리블록은 다른 이름으로 여러 힌트에서 반복 사용될 수 없다. 이 힌트를 사용하면서 명명하지 않는 쿼리블록은 옵티마이져가 쿼리 블록명을 자동 생성하며, | ||
===REWRITE_OR_ERROR=== | ===REWRITE_OR_ERROR=== | ||
- | 적합한 실체뷰가 존재하지 않아서 옵티마이져가 쿼리 재생성을 실행할수 없는 경우 만약 이 힌트가 지정되어 있으면 ORA-30393에러를 유발하여 쿼리 수행을 중단 시키도록 하는 힌트이다. | + | * **적합한 실체뷰가 존재하지 않아서 옵티마이져가 쿼리 재생성을 실행할수 없는 경우** 만약 이 힌트가 지정되어 있으면 ORA-30393에러를 유발하여 쿼리 수행을 중단 시키도록 하는 힌트이다. |
- | 예) SELECT /*+ REWRITE_ OR_ERROR */ p.prod_subcatgory, | + | |
SUM(s.amount_sold) | SUM(s.amount_sold) | ||
FROM sales s, products p | FROM sales s, products p | ||
줄 116: | 줄 145: | ||
+ | ==참조한문서== | ||
+ | " |