지난 한달동안 규모가 좀 있는 프로젝트 파견을 다녀왔다. 그곳에는 DB를 담당하시는 분들, 인프라를 담당하시는 분들 PM,PL 등등 많은 사람들이 있었고, 나는 그중에도 DB를 담당하시는 과장님과 교류를 많이 했던 거 같다. 당시 내가 짰던 쿼리는 데이터가 너무 많아서 리딩하는데 시간이 너무 많이 걸렸고, 이러한 문제가 발생했을 때 과장님께 쿼리 튜닝을 부탁드렸다. 그 중 블로그에 다루고 싶었던 내용이 있는데 그것이 바로 hint 이다.
힌트는 SQL 튜닝의 핵심 부분으로 일종의 지시 구문이며 SQL에 포함되어 쓰여져 Optimizer의 실행계획을 원하는 대로 바꿀 수 있게 해준다. 디비의 Optimizer 라고 해서 항상 최선의 실행계획을 수립할 수는 없으므로 테이블이나 인덱스의 잘못된 실행 계획을 개발자가 직접 바꿀 수 있도록 도와주는 것이 HINT 이다.
SELECT 첫 줄에 힌트 주석을 작성하여 적절한 인덱스를 사용하도록 유도한다.
( /+ ..... /)
/+ ALL_ROWS /
설명 : 가장 좋은 단위 처리량의 목표로 문 블록을 최적화하기 위해 cost-based 방법을 선택한다. (즉, 전체적인 최소의 자원 소비)
/+ CHOOSE /
설명 : 최적자(optimizer)가 그 문에 의해 접근된 테이블을 위해 통계의 존재에 두는 SQL 문을 위해 rule-based 접근 방법과 cot-based 접근 방법 선택하게 한다.
/+ FIRST_ROWS /
설명 : 가장 좋은 응답 시간의 목표로 문 블록을 최적화하기 위해 cost-based 접근 선택한다. (첫 번째 행을 되돌려 주는 최소의 자원 사용)
/+ RULE /
설명 : 최적화를 고르는 접근방법을 선택한다.
/+ AND_EQUAL(table index) /
설명 : 그만큼 실행 계획을 선택한다. 그리고 여럿의 single-column 색인에 scan을 합병하는 접근 경로를 사용한다.
/+ CLUSTER(table) /
설명 : 명시 적으로 클러스터 스캔을 선택하여 지정된 테이블에 액세스한다.
/+ FULL(table) /
설명 : 명시 적으로 지정된 테이블에 대한 전체 테이블 스캔을 선택한다.
/+ HASH(table) /
설명 : 명시 적으로 해시 검색을 선택하여 지정된 테이블에 액세스한다.
/+ HASH_AJ(table) /
설명 : 지정된 테이블에 액세스하기 위해 NOT IN 부속 조회를 해시 antijoin으로 변환한다.
/+ HASH_SJ (table) /
설명 : NOT IN 하위 쿼리를 해시 방지 조인으로 변환하여 지정된 테이블에 액세스 한다.
/+ INDEX(table index) /
설명 : 명시 적으로 지정된 테이블에 대한 인덱스 스캔을 선택한다.
/+ INDEX_ASC(table index)
/설명 : 명시 적으로 오름차순 범위 인덱스 스캔을 선택한다.
/+ INDEX_COMBINE(table index) /
설명 : INDEX_COMBINE 힌트에 대한 인수로 인덱스가 제공되지 않으면 옵티마이 저는 비트 맵 인덱스의 부울 조합이 비용 예상치가 가장 높은 것을 사용한다.특정 인덱스가 인수로 제공되면 옵티마이 저는 특정 비트 맵 인덱스의 일부 부울 조합을 사용하려고 시도한다.
/+ INDEX_DESC(table index) /
설명 : 지정된 테이블에 대해 내림차순 범위 스캔을 명시 적으로 선택한다.
/+ INDEX_FFS(table index) /
설명 : 전체 테이블 스캔이 아닌 빠른 전체 인덱스 스캔이 수행되도록 한다.
/+ MERGE_AJ (table) /
설명 : NOT IN 하위 쿼리를 병합 방지 조인으로 변환하여 지정된 테이블에 액세스 한다
/+ MERGE_SJ (table) /
설명 : 상관 된 EXISTS 부속 조회를 병합 semi-join으로 변환하여 지정된 표에 액세스한다.
/+ ROWID(table) /
설명 : 명시 적으로 지정된 테이블에 대해 ROWID에 의한 테이블 스캔을 선택한다.
/+ USE_CONCAT /
설명 : UNION ALL 집합 연산자를 사용하여 쿼리의 WHERE 절에서 조합 된 OR 조건을 복합 쿼리로 변환 하도록 한다.
/+ LEADING(테이블) /
설명 : Driving 테이블 결정, 힌트에 명시된 테이블이 먼저 Driving 한다.
/+ ORDERED /
설명 : Oracle은 FROM 절에 나타나는 순서대로 테이블을 조인한다.
/+ STAR /
설명 : 인덱스에서 중첩 루프 조인을 사용하여 큰 테이블을 마지막으로 조인 하도록 한다.
/+ DRIVING_SITE (table) /
설명 : 오라클이 선택한 사이트와 다른 사이트에서 쿼리 실행을 강제한다.
/+ USE_HASH (table) /
설명 : Oracle이 해시 조인을 사용하여 다른 행 소스와 함께 지정된 각 테이블을 조인하도록 한다.
/+ USE_MERGE (table) /
설명 : 오라클이 sort-merge 조인을 사용하여 다른 행 소스와 함께 지정된 각 테이블을 조인하게 한다.
/+ USE_NL (table) /
설명 : 지정된 테이블을 내부 테이블로 사용하여 중첩 루프 조인을 사용하여 Oracle이 지정된 각 테이블을 다른 행 소스에 조인하도록 한다.