오라클 힌트

출처

이 포스트는 기존에 Oracle Hint에 대한 공부중 스크랩한 내용으로
구루비 지식창고의 내용이 포함되어 있습니다.
출처 : http://wiki.gurubee.net/dashboard.action

힌트란?

옵티마이저는 데이타 분포도가 좋고 최신 통계가 있어야 좋은 실행계획을 세운다.
하지만 HINT절을 사용하면 옵타마이저의 실행계획을 개발자가 지정할 수 있다.
예를 들면 INDEX SCAN을 강제로 FULL TABLE SCAN으로 변경할 수 있다.

문법

  • {DELETE|INSERT|SELECT|UPDATE} /*+ hint [text] [hint[text]]… */
  • {DELETE|INSERT|SELECT|UPDATE} –+ hint [text] [hint[text]]…

종류

  • RULE : RBO 옵티마이저 사용
  • FIRST_ROWS : 첫번째 레코드 추출을 최소화할 목적으로 사용시
  • ALL_ROWS : 모든 레코드의 처리시간을 최소화할 목적으로 사용시
  • FULL : 테이블의 전체 스캔
  • ROWID : 테이블의 ROWID 스캔
  • CLUSTER : 테이블의 클러스터 스캔
  • HASH : 테이블의 해쉬 스캔

정렬방법

  • INDEX_ASC : 오름차순 INDEX 스캔
  • INDEX_DESC : 내림차순 INDEX 스캔
  • AND_EQUALS : 여러 인덱스를 MERGE하여 사용 (2~5개)
  • ORDERED : FROM절에 기술된 TABLE 순으로 Join
  • USE_NL : Nested Loop Join
  • USE_MERGE : Sort Merge Join

예제

아래의 HINT를 사용하기 전/후의 실행계획을 비교하는 예제입니다.

힌트

APPEND

데이터를 입력하는 INSERT문에서 사용하는 힌트이다. 이 힌트는 데이터 입력작업을 ‘DIRECT-PATH’방식으로 수행되도록 하여 SGA를 거치지 않고 직접 저장공간으로 입력이 되도록 함으로써 매우 빠른 입력처리를 보장한다. 한가지 유의할 점은 반드시 최고 수위점(High water mark)다음 위치에 데이터를 저장한다는 것이다.

NOAPPEND힌트는 INSERT문을 처리할때 ‘CONVENTIONAL-PATH’방식으로 수행하도록 유도하기 위해 사용한다. 이 방식은 기본적으로 직렬모드(Serial mode)로 수행되고 ‘DIRECT-PATH’방식은 병렬모드로 수행된다.

CACHE

전체 테이블 스캔방식으로 읽혀진 블록을 데이터베이스의 버퍼캐쉬를 관리하는 LRU 리스트의 최근 사용위치 (Most Recent Used End)에 머물도록 하여 계속해서 메모리 내에 머물 수 있도록 하는 힌트이다.
크키가 작은 테이블에 유용하게 사용될수 있다. 이 힌트를 사용하면 옵티마이져는 테이블에 이미 정의되었던 기본 캐쉬(Default Caching)정의를 무효화한다.

NOCAHCE

전체테이블 스캔 방식으로 읽혀진 블록을 데이터베이스 버퍼 캐쉬의 LRU리스트의 끝에 위치하도록 유도함으로써 메모리 내에서 우선적으로 제거되도록 하는 힌트이다. 이것은 데이터베이스버퍼 캐쉬에서 옵티마이져가 블록을 관리하는 일반적인 방법이기도 하다.

CARDINALITY

옵티마이져에게 해당 쿼리 전체나 일부 구성에 대한 카디널러티 예상 값을 제시하여 실행계획 수립에 참조하도록 하는 힌트이다. 힌트에 테이블을 지정하지 않으면 이때의 카디널러티는 전체 쿼리를 수행한 결과로 얻어진 총 건수로 간주한다.

CURSOR_SHARING_EXACT

만약 CURSOR_SHARING 초기화 파라메터가 ‘EXACT’로 지정되어 있다면 리터럴 값을 바인드 변수로 변경하지 않고 있는 그대로 파싱을 한다. FORCE와 SIMILAR를 지정하면 SQL조건절에 상수값을 지정했다라도 옵티마이져는 변수로 인정하여 실행계획을 수립하므로 실행계획의 공유비율을 높일 수 있다. 또한 우리는 경우에 따라서 ‘ALTER SESSION …’명령을 이용하여 이 파라메터를 조정하기도 한다. 그러나 SQL에서 지정한 상수값에 따라 미묘하게 달라지는 실행계획을 얻을 수 없으므로 이 힌트를 이용하여 CURSOR_SHARING 파라메터를 ‘EXACT’로 지정한것과 동일한 상태로 만들수 있다.

DRIVING_SITE

원격(Remote)테이블과 조인(분산쿼리)을 할 때 쿼리가 수행될 사이트를 지정하여 분산쿼리를 최적화하는데 적용하는 힌트이다.

DYNAMIC_SAMPLING

우리가 통계정보를 생성해두지 않았더라도 언제나 비용기준으로 작동할수 있게 하기위한 동적 표본화(Dynamic sampling)는 옵티마이져를 설명하면서 소개 한적이 있다. 이 기능은 통계정보를 가지고 있지않거나, 에러 등의 문제로 사용할수 없게 되거나, 너무 오래되어 더 이상 신뢰할수 없을 때 적용한다.
샘플링 레벨은 0~10 사이로 줄수 있으며, 값이 클수록 더욱 정확한 통계정보를 수집하게 된다. 이 힌트는 바로 이 기능을 단위 SQL에 적용할수 있기 위해 탄생되었다.

어떤 테이블에 대한 카디널러티 통계가 있을 때 만약 테이블 하나만 액세스하는 쿼리에 조건절이 없는 상태에서 이 힌트를 사용하면 옵티마이져는 현존하는 통계정보를 선택하고 이 힌트를 무시한다.

반대로, 이 상황에서 조건절이 존재하면 옵티마이져는 현존하는 카디널리티 통계를 이용하여 조건문의 선택도를 추정함으로써 이 힌트를 적용하게 된다.

PUSH_PRED

뷰나 인라인뷰의 외부에 있는 조인 조건을 뷰 쿼리 내로 삽입하도록 하는 힌트이다. 즉, 아래 SQL은 인라인뷰가 수행된 결과와 조인을 하는 것이 아니라 직접 조인을 한것처럼 외부의 조인조건에 의해 조인을 수행한 후 체크 기능이 수행된다.

NO_PUSH_PRED

뷰나 인라인뷰의 외부에 있는 조인조건을 뷰 쿼리 내로 삽입하지 않도록 하는 힌트이다.
아래 SQL은 인라인뷰가 먼저 수행한 결과와 조인이 수행된다.

PUSH_SUBQ

이 힌트는 머지되지 않는 서브쿼리를 최대한 먼저 수행할 수 있도록 실행계획을 수립하기를 요구한다. 머지가 된 서브쿼리는 먼저 수행되고 그 결과를 메인쿼리의 처리범위를 줄이는 ‘제공자’역활을 한다. 그러나 일반적으로 머지가 불가능해지면 ‘확인자’역활을 해야 하기 때문에 실행계획의 마지막 단계에서 수행된다. 만약 머지를 할수 없는 서브쿼리가 상대적으로 적은 로우를 가지고 있거나 처리범위를 줄여 주는데 중요한 역활을 할 수 있다면 이 힌트를 이용하여 최대한 앞 부분에서 수행되도록 함으로써 수행속도 향상을 얻을 수 있다.
예를 들어 어떤 쿼리가 선택한 결합 인덱스에서 중간에 있는 컬럼에 조건이 부여되지 않았을때 ‘=’조건을 공급하기 위해서 서브쿼리를 추가 했는데 우리의 생각과는 달리 서브쿼리가 확인자의 역활을 하도록 실행계획이 수립된다면 이 힌트를 이용하여 제공자 역활을 하도록 할수 있다.

그러나 그 서브쿼리가 원격 테이블이거나 Sort Merge조인의 일부로써 수행될 때는 이 힌트는 아무런 역활도 하지 못한다.
NO_PUSH_SUBQ 힌트는 옵티마이져가 머지되지 않는 서브쿼리르 제일 나중에 수행되도록한다. 만약 이러한 서브쿼리가 처리범위를 거의 줄여주지 못하거나 상대적으로 부담이 된다면 가능한 가장 마지막에 처리하는것이 유리한다.
다시 말해서 다른 조건들이 최대한 적용되어 가장 많이 줄여진 다음에 수행되는것이 유리하다.

QB_NAME

쿼리 블록에 이름을 부여하여 해당 쿼리 블록 외부의 다른 힌트에서 지정한 쿼리블록을 참조할 수 있도록 하는 힌트이다.

쿼리 블록에 대한 명칭은 전체 쿼리 내에 유일하게 부여되어야 하며, 동일한 쿼리블록은 다른 이름으로 여러 힌트에서 반복 사용될 수 없다. 이 힌트를 사용하면서 명명하지 않는 쿼리블록은 옵티마이져가 쿼리 블록명을 자동 생성하며, 사용된 쿼리블록명은 PLAN_TABLE에서 확인할수 있다.

REWRITE_OR_ERROR

적합한 실체뷰가 존재하지 않아서 옵티마이져가 쿼리 재생성을 실행할수 없는 경우 만약 이 힌트가 지정되어 있으면 ORA-30393에러를 유발하여 쿼리 수행을 중단 시키도록 하는 힌트이다.

퀴리형태 변형(Query Transformation)을 위한 힌트

USE_CONCAT

조건절에 있는 OR 연산자 조건(또는 IN 연산자 조건)을 별도의 실행단위로 분리하여 각각의 최적의 액세스 경로를 수립하여 이를 연결(Concatenation)하는 실행계획을 수립하도록 유도하는 힌트이다.
반드시 처리주관 조건이 OR로 나누어졌을 때 적용해야 하며, 잘못 사용하면 비효율이 발생할 수 잇으므로 주의해야 한다.

NO_EXPAND

조건절에 있는 OR연산자 조건(또는 IN 연산자 조건)을 연결 실행계획으로 처리되지 않도록 할 때 사용하는 힌트이다. 즉, USE_CONCAT의 반대 개념이다.

REWRITE

대량의 데이터를 대상으로 하는 조인이나 그룹함수 사용하여 가공집합을 얻고자할 때 수행속도 향상을 위해 미리 생성된 실체뷰(Materialized View)를 생성할수 있다. 우리가 어떤 쿼리를 수행하였을 때 옵티마이져는 원래의 테이블을 액세스하는 방법과 실체뷰를 액세스하는 방법 중에서 유리한 것을 선택하도록 쿼리를 변형할수 있다. 이것을 ‘쿼리 재작성(Query rewrite)’이라고 하는데 이 힌트는 이러한 과정을 실행하도록 하는 힌트이다.
만약, 힌트내에 특정 실체뷰가 지정되어 있으면 비용에 상관없이 해당 실체뷰를 사용하게 된다. 이 때 힌트 내에 포함되지 않는 실체뷰는 고려대상이 아니다. 만약 힌트내에 실체뷰를 지정하지 않으면 적용 가능한 실체뷰를 찾아서 비용에 상관없이 그 실체뷰를 사용한다.

NO_REWRITE

이 힌트는 QUERY_REWRITE_ENABLED 파라메터가 TRUE로 정의되어 있더라도 이를 무시하고 쿼리 블록에 대한 쿼리 재생성를 하지 않도록 유도한다.

이것은 실체뷰를 통해 쿼리 수행결과를 미리 저장하고 있는 경우에는 원래의 테이블로부터 직접 재계산을 유도함으로써 최신의 값으로 결과를 출력하도록 할 때 유용하게 사용된다. 버전에 따라 NO_REWRITE로 사용되기도 한다.

MERGE

뷰나 인라인뷰의 액세스를 최적화기 위해서는 뷰쿼리에 사용된 원래의 테이블을 최적으로 액세스하도록 문장을 변환시켜야 한다. 이 과정을 뷰병합이라고 하며, 주어진 상황에 따라 다양한 현상이 나타난다. 이 힌트는 뷰병합이 가능함에도 불구하고 뷰병합이 일어나지 않을 때 적용할수 있다. 주로 복잡한 뷰나 인라인 뷰일 때 가끔 적용해 보면 상당한 효과를 얻는 경우가 많이 있다.

NO_MERGE

뷰쿼리 병합이 일어나지 않도록 요구하는 힌트이다. 주어진 조건이나 처리형태에 따라 뷰 병합을 하지 않고 먼저 뷰를 수행한 결과를 이용해 다음 처리를 하는 것이 유리한 경우도 많이 있다. 이러한 경우에 뷰 병합을 방지하기위해 사용하는 힌트 이다.

STAR_TRANSFORMATION

스타 변형 조인(Star transformation join)을 수행하도록 요구하는 힌트이다. 이조인은 소량의 데이터를 가진여러 개의 디멘전 테이블과 팩트 테이블의 개별 비트맵 인덱스를 이용하여 처리범위를 줄이는 조인방식이다. 이 조인은 내부적으로 옵티마이져가 질의를 변형하여 실행계획을 생성하게 한다.

NO_STAR_TRANSFORMATION 힌트는 옵티마이져로 하여금 스타변형 조인을 하지 않도록 유도한다.

FACT

스타변형 조인에서 팩트 테이블을 지정하기 위해서는 사용하는 힌트이다. 대부분의경우는 옵티마이져에게 맡기는 것이 바람직하지만 팩트 테이블 선정에 오류가 있어서 원하지 않는 실행계획이 나타났을때 사용할수 있다. NO_FACT힌트는 지정한 테이블을 팩트 테이블로 인정하지 말아달라는 요구를 하는 힌트이다.
NO_FACT 힌트는 STAR_TRANSFORMATION 상황에서 옵티마이져가 지정한 테이블을 FACT테이블로 고려하지 않도록 유도한다.

UNNEST

서브쿼리와 메인쿼리를 합쳐 조인 형태로 변형하도록 하는 실행계획을 생성하도록 유도하는 힌트이다.

NO_UNNEST힌트는 UNNESTING을 하지 않도록 유도한다.

액세스 수단 선택을 위한 힌트

FULL

힌트 내에서 정의된 테이블을 전체테이블 스캔 방식으로 유도하는 힌트이다.

HASH

해쉬 클러스터 테이블을 액세스할 때 해쉬 스캔방식으로 액세스하도록 유도하는 힌트이다.

CLUSTER

클러스터링 테이블을 액세스할 때 클러스터 인덱스를 통해 스캔하도록 유도하는 힌트이다.

INDEX

인덱스 범위 스캔에의한 테이블 액세스를 유도하는 힌트이다. 뷰를 액세스하는 쿼리의 경우 뷰 쿼리 내에서는 테이블에 대한 인덱스 스캔을 지정할 수도 있다.

여기서 cust_v는 cust테이블 액세스를 포함하고 있는 View이름이며, cname_idx는 cust 테이블의 cust_name컬럼에 대해 정의된 인덱스임.

NO_INDEX

옵티마이져가 실행계획을 수립할 때 지정한 인덱스는 제외하고, 다른 액세스 방법을 고려하도록 유도하는 힌트이다.

여기에 지정한 인덱스를 제외한 나머지 인덱스들을 액세스 수단으로 고려한다. 그러나 만약 인덱스를 지정하지 않고 테이블만 정의하면 해당 테이블의 모든 인덱스을 힌트 내에 정의한 것으로 인정하여 모든 인덱스를 고려 대상에서 제외한다. 동일한 인덱스를 NO_INDEX힌트와 함께 INDEX, INDEX_ASC, INDEX_DESC, INDEX_COMBINE, INDEX_FFS등에 사용하면 옵티마이져는 두 힌트 모두를 무시한다.
이런 특성을 이용해 여러분이 튜닝을 위한 테스트를 할 때 기존에 부여했던 힌트를 지우지 않고 잠시 무시하도록 하기 위해 사용할수 있다. 또한 뷰 쿼리에 삽입한 힌트를 무시하고자 할 때도 적용할 수있다.

INDEX_ASC

인덱스를 경유하여 테이블을 액세스할때 힌트에 지정한 인덱스를 인덱스 컬럼값의 오름차순(정순)으로 범위 스캔하도록 유도하는 힌트이다.

INDEX_DESC

인덱스를 경유하여 테이블을 액세스할때 힌트에 지정한 인덱스를 인덱스 컬럼값의 내림차순(역순)으로 범위 스캔하도록 유도하는 힌트이다.

INDEX_COMBINE

2개의 이상의 인덱스를 비트맵 인덱스로 변경/결합하여 테이블을 액세스하는 방식으로 유도하는 힌트이다. 해당 인덱스, 비트맵 인덱스 모두 가능하며, 서로 다른 타입의 인덱스에서도 변경/결합이 가능하다.
INDEX_COMBINE 힌트에서 테이블 이름만 부여하고 인덱스 이름을 명시하지 않으면 옵티마이져가 해당 테이블에서 가장 적합한 인덱스를 선택하여 처리한다.

INDEX_FFS

전체 테이블을 스캔하는 것과 유사한 방법으로 인덱스 전체범위를 스캔하는 방식으로 유도하는 힌트이다. 비록 인덱스를 스캔하지만 다중블록을 스캔한다.

이와 반대로 NO_INDEX_FFS 힌트에서 지정한 테이블의 인덱스에대해 ‘고속 전체 인덱스 스캔’방식을 제외한 다른 액세스 방법을 사용하도록 유도한다.

INDEX_JOIN

2개 이상의 인덱스들만으로 조인을 수행하도록 유도하는 힌트이다. 이 때 인덱스를 구성하는 컬럼이 해당 질의에서 필요로 하는 모든 컬럼을 포함하고 있어야 한다.
즉, 테이블을 전혀 액세스하지 않고 인덱스들만으로 쿼리를 처리할수 있어야 한다.
인덱스 조인은 2개 이상의 인덱스를 범위 스캔한 결과를 ROWID로 해쉬 조인을 수행하여 결과를 얻는다.

INDEX_SS

인덱스 스킵 스캔 방식으로 인덱스를 액세스하도록 유도하는 힌트이다.

이와 반대로 NO_INDEX_SS 힌트는 힌트에서 지정한 테이블의 인덱스에 대해 스킵스캔을 제외한 다른 액세스 방법을 사용하도록 유도한다.

INDEX_SS_ASC

인덱스 스킵 스캔방식으로 범위 스캔하는 경우 오름차순으로 인덱스를 읽도록 하는 힌트이다.

INDEX_SS_DESC

인덱스 스킵 스캔방식으로 범위 스캔하는 경우 내림차순으로 인덱스를 읽도록 하는 힌트이다.

병렬처리 관련 힌트

병렬처리에 관련된 힌트들은 시스템 자원을 많이 사용하게 되므로 사용자의 요구에 따라 결정되어야 한다.
이런 유형의 힌트는 처리방법을 개선하여 일의 량을 줄이는 것이 아니라 시스템 자원을 최대한 사용하더라도 결과를 얻는 절대 시간을 줄이겠다는 것이 목적이다.
병렬처리는 시스템에 부하를 주더라도 수행시간을 당기는 것이더 필요할 때 적용하는 처리방법이다. 그러므로 가능하다면 기본값(Default value)을 사용하지 말고, SQL단위에서 힌트를 사용하여 적용하는것이 바람직하다.
병렬처리 힌트는 병렬처리에서 나타나는 병렬프로세스들의 개수를 지정하거나 내부처리방법에 대한 우리의 요구를 전달하기 위해 사용한다. 특히 병렬 프로세스의 개수는 수행시간 및 시스템의 부하에 직접적인 영향을 미치므로 매우 중요하다.

PARALLEL

대량의 데이터에 대한 테이블을 액세스 할 때와 DML을 처리할 때 SQL의 병렬처리를 지시하는 힌트이다. 일반적으로 병렬 스레드(Parallel threads)를 나타내는 숫자와 함께 사용하고 있다.
만약 힌트에 병렬도(Parallel Degree)를 나타내는 숫자를 정의하지 않으면 옵티마이져는 PARALLEL_THREADS_PER_CPU 파라메터에 정의된 값을 자동으로 계산해서 적용한다.
만약 테이블 정의할 때 ‘PARALLEL’을 지정하였다면, 힌트를 사용하지 않아도 병렬처리가 가능한 경우에는 이 병렬도를 적용한다. 그러나 DELETE, INSERT, UPDATE, MERGE등의 DML문장을 병렬로 수행하기 위해서는 반드시 세션을 ‘ALTER SESSION ENABLE PARALLEL DML’로 지정해야만 병렬처리가 가능하다. 한 번 지정한 병렬도는 내부적으로 GROUP BY나 정렬처리 등의 단위작업에도 재차 적용될수 있다. 만약 병렬처리에 어떤 제한 요소가 발생하게 되면 이 힌트는 무시된다.

NOPARALLEL

테이블을 정의 시에 PARALLEL옵션을 부여하면 쿼리에 직접 힌트를 주지 않아도 옵티마이져는 병렬처리가 가능하다고 판단되면 병렬처리 실행계획을 수립한다. 이때 SQL에 이 힌트를 적용하면 옵티마이져는 해당 테이블의 PARALLEL파라메터를 무시하고 병렬처리를 하지 않는 실행계획을 수립하게 된다.

PQ_DISTRIBUTE

병렬 조인의 속도를 향상시키기 위해 슬레이브 프로세스 – 생산자(Producer)와 소비자(Consumer)프로세스 – 사이에서 조인할 테이블의 로우를 서로 주고 받는 할당작업(Distrubution)을 하는 방법을 정의 하는 힌트이다.
표현 방식:

  • outer_distribution: 외측 테이블에 대한 할당 방법을 기술
  • inner_distribution: 내측 테이블에 대한 할당 방법을 기술
  • 할당방법 :
    — HASH: 조인 키 컬럼에 대해 해쉬 함수를 수행한 결과값을 이용하여 소비자 프로세스에 로우들을 할당
    — BROADCAST: 외측 테이블에 전체 로우를 모든 Consumer 프로세스로 보냄
    — PARTITON: 상대편 조인 대사 테이블이 조인 키 컬럼으로 파티션되어 있는 경우 파티션 키 값을 이용하여 로우들을 Consumer프로세스에 할당
    — NONE: 조인 대상 로우들을 랜덤하게 파티셔닝함

PARALLEL_INDEX

파티션 인덱스(Partitioned Index)에 대한 인덱스 범위 스캔을 병렬로 수행하기 위한 병렬도를 지정하는 힌트이다.

NOPARALLEL_INDEX

인덱스 생성(Create)이나 변경(Alter)에 의해 PARALLEL 파라메터가 적용되어 있는 경우 SQL에서 이 힌트를 적용하면 옵티마이져는 해당 인덱스에 대한 PARALLEL 파라메터를 무시하여 범위스캔을 하지 않게 된다.

NOPARALLEL_INDEX힌트는 버전에 따라 NO_PARALLEL_INDEX힌트로 대체되어 사용되기도 한다.

※ Oracle버전별 NOPARALLEL_INDEX Hint
– Oracle9iR2 (NOPARALLEL_INDEX)
– Oracle10gR2,11gR1 (NO_PARALLEL_INDEX)

조인 방법 선택용 힌트

조인방식을 선택하기위해 적용하는 힌트를 사용하는 것은 먼저 조인 방식에 대한 확실힌 이해가 바탕이 되야 한다.
부분범위 처리의 가능여부나, 인덱스의 구성상태, 처리범위나 사용빈도, 메모리의 가용상태와 작업영역(hash_area_size, sort_area_size 등)에 영향을 받는다.
쿼리가 수행되는 시간대나 시스템의 유형(OLTP, OLAP등)에도 영향을 받을 수 있다.

USE_NL

Nested Loops방식을 사용하여 조인을 수행하도록 유도하는 힌트이다.
이 힌트는 대상 집합 간의 조인 방식을 지칭할 뿐이며, 조인 순서에는 영향을 미치지 않는다.

NO_USE_NL

USE_NL 힌트가 옵티마이져에게 지정한 테이블에 대한 조인 방식을 제시하는 것인데 반해, NO_USE_NL 힌트는 옵티마이져에게 지정한 테이블에 대해 Nested Loop 조인방식을 제외한 다른 방식의 조인-해쉬조인 이나 Sort Merge 조인등 -을 사용할을 제시한다. 옵티마이져의 실행계획 수립에 대해 USE_NL이 적극적인 개입이라면 NO_USE_NL은 소극적인 개입이라고 할 수 있다.
Nested Loops조인이 최적이라 판단되는 상황에서는 옵티마이져가 이 힌트를 무시할수도 있다.

USE_NL_WITH_INDEX

Nested Loops조인에서 선행처리되는 외측루프의 처리주관 인덱스를 지정할 때 사용하는 힌트이다. 과거에는 USE_NL 과 INDEX 힌트를 같이 사용하였지만 이 힌트는 이들을 하나로 통합한 것이다.

만약 이 힌트에서 인덱스를 지정하지 않았다면, 내측 루프의 연결고리 인덱스가 정상이어야 외측루프(선행 테이블)의 어떤 인덱스가 처리주관 인덱스로 사용될 수 있다. 만약 특정 인덱스를 지정하였다면, 내측 루프의 연결고리가 정상일 때 지정한 인덱스가 적용될 수 있다.

USE_HASH

해쉬조인 방식으로 조인이 수행되도록 우도하는 힌트이다. 해쉬조인은 어느 한쪽 테이블이작아서 인-메모리 해쉬조인으로 수행될 수 있다면 매우 양호한 속도를 갖는다.
대부분 경우는 옵티마이져가 통계정보를 토대로 빌드 입력과 검색입력을 결정하므로 일부러 ‘ordered’힌트를 주어 함부로 순서를 결정하는 것은 바람직하지 못하다.
그러나 옵티마이져의 판단에 문제가 있을 때나 인라인뷰에서 가공한 결과 집합처럼 적절한 통계정보를 가질 수 없는 경우에는 활용가치가 있다.

이와 반대로 NO_USE_HASH 힌트는 옵티아미져가 지정하 테이블들을 조인하는 데 있어서 해쉬 조인을 제외한 다른 방식의 조인을 고려하도록 유도한다.

USE_MERGE

Sort Merge방식으로 조인을 수행하도록 유도하느 힌트이다. 필요하다면 ‘ordered’힌트와 같이 사용할 것을 추천한다.

이와는 반대로 NO_USE_MERGE 힌트는 옵티마이져가 지정한 테이블을 조인하는데 있어서 Sort Merge조인을 제외한 다른 방식의 조인을 고려하도록 유도한다.

조인 순서 조정을 위한 힌트

이 힌트는 다수의 테이블을 조인하는 경우에 조인 순서에 혼선이 있을 때 적용하는 것이 가장 일반적이다.
Sort Merge 조인 이나 해쉬조인에서는 적은 테이블을 먼저 처리하도록 유도할 때 사용하는 것이 좋다.

ORDERED

FROM절에 기술된 테이블 순서대로 조인을 수행하도록 유도한다.
만약 LEADING 힌트와 함께 사용하면 LEADING 힌트는 무시된다.

ORDERED 힌트는 액세스 순서만 제시할 뿐이고, 조인 방법 과는 무관하기 때문에 조인방법을 유도하기 위한 USE_NL, USE_MERGE등의 힌트와 함께 사용하는 것이 일반적이다.

LEADING

FROM절에 기술한 테이블의 순서와 상관없이 조인 순서를 제어하는 힌트로서 ORDERED 힌트와는 달리 FROM절을 변경 필요 없이 사용할 수 있다.
ORDERED 힌트와 함께 사용되면 무시된다.

최적화 목표(Goal) 제어 힌트

어떤 쿼리에서 기본적으로 생성된 실행계획이 만족스럽지 못할 때 일단 옵티마이져 모드를 바꾸어서 그 결과를 살펴보는 것을 목적으로 하는 정도로 적용하는것이 좋음

ALL_ROWS

쿼리 전체 결과를 모두 수행하는 것에 대한 최적화(Best throughput)를 목표로 최저 비용의 실행계획을 수립하도록 유도한다.(Minimum total resource consumption)

CHOOSE

SQL에서 액세스하는 테이블에 대한 통계정보 유무에 따라 규칙기준이나 비용기준을 적용하여 최적화를 수행한다. 만약 CHOOSE모드에서 테이블의 통계정보를 참조할수 있는 경우에는 ALL_ROWS 방식으로 처리된다.

FIRST_ROWS

최적응답시간(Best response time)을 목표로 최저 비용의 실행계획을 수립하도록 유도한다. (Minimum resource usage to return first or first n rows)

RULE

규칙기준 옵티마이져를 이용한 최적화를 요구한다. 즉, 조건구문에 사용된 컬럼들의 인덱스 형태나 연산자 형태 등 에 의한 우선순위 규칙에 실행계획을 수립하도록 유도한다.

CC BY-NC-ND 2.0 KR

이 저작물은 크리에이티브 커먼즈 저작자표시-비영리-변경금지 2.0 대한민국 라이선스에 따라 이용할 수 있습니다. 크리에이티브 커먼즈 라이선스

저작권과 관련된 파일요청 및 작업요청을 받지 않습니다.

댓글 남기기