오라클 힌트는 SQL 튜닝의 핵심 부분이다.
오라클이 스스로 항상 최적의 실행을 하는 것이 힘들기 때문에 힌트를 통해 직접 최적의 실행방법을
지시해주기 위한 것이다.
물론 무분별한 힌트의 사용은 오히려 성능의 저하를 초래하기 때문에 힌트를 잘 알고 적절하게 사용하기 바란다.
■ 힌트절의 형태
/*+ hint */
/*+ hint(argument) */
■ 힌트의 종류
-옵티마이저의 목표에 따른 힌트
-접근 경로에 따른 힌트
-쿼리 변환에 따른 힌트
-조인 순서에 따른 힌트
-조인 방법에 따른 힌트
1. 옵티마이저의 목표에 따른 힌트
/*+ ALL_ROWS */
: 질의의 모든 결과를 반환하는 힌트
/*+ FIRST_ROWS */
: 조건에 맞는 첫 번째 row를 반환하고 Resource 소비를 최소화
: Cost-Based 접근방식을 사용.
: 집합 연산자 (UNION, INTERSECT, MINUS, UNION ALL), Group 함수 에서는 제외
/*+ CHOOSE */
: 통계정보에 따라 최적화 방법을 옵티마이저가 RBO와 CBO 중 하나를 선택
RBO(Rule Based Optimization), CBO(Cost Based Optimization)
2. 접근 경로에 따른 힌트
/*+ FULL(table_name) */
: Table을 Full Scan
/*+ CLUSTER(table_name) */
: Table을 Cluster Scan
/*+ HASH(table) */
: Table을 Hash scan
/*+ INDEX(table_name index_name) */
: Table을 index scan
/*+ NO_INDEX(table_name index_name) */
: index scan을 사용하지 않음
/*+ INDEX_COMBINE(table_name index_name) */
: Table의 비트맵 접근 경로 사용
/*+ INDEX_FFS(table index) */
: fats full index scan 사용
/*+ INDEX_ASC(table_name index_name) */
: Table을 오름차순으로 index scan
/*+ INDEX_DESC(table_name index_name) */
: Table을 내림차순으로 index scan
/*+ INDEX_SS(table_name index_name) */
: index skip scan 사용
3. 쿼리 변환에 따른 힌트
/*+ NO_QUERY_TRANSFORMATION */
: 쿼리를 변환하지 않음
/*+ USE_CONCAT */
: OR 조건을 UNION ALL 로 변환
/*+ NO_EXAPAND */
: OR 조건을 UNION ALL 로 변환하지 않음
/*+ REWRITE */
: MView에 대해 쿼리를 다시 작성
/*+ MERGE */
: 쿼리에 사용된 뷰들을 병합
/*+ UNNEST*/
: 서브쿼리를 조인 문으로 변환
4. 조인 순서에 따른 힌트
/*+ LEADING(table_name1, ..._) */
: 파라미터에 명시된 순서대로 테이블 조인
/*+ ORDERED */
: FROM 절에 명시된 순서대로 조인
5. 조인 방법에 따른 힌트
/*+ USE_NL (table_name) */
: Nested Loop Join 사용
/*+ USE_NL_WIDTH_INDEX (table_index) */
: 인덱스를 이용한 Nested Loop Join 사용
/*+ USE_MERGE (table_name) */
: 머지 조인(Merge Join)이 일어나도록 유도하며, SORT를 동반하므로 SORT MERGE JOIN
/*+ USE_HASH (table_name) */
: Hash Join을 사용
■ 일반적인 SQL 튜닝 기법
1. 바인드 변수를 사용한다.
: 상수 값이 변경되어도 이전 질의를 사용함으로 최적화 실행단계를 줄인다.
2. 가급적 WHERE 절의 조건에 인덱스 컬럼을 모두 사용한다.
3. 인덱스 컬럼에 사용하는 연산자는 가급적 = 을 사용한다.
4. 인덱스 컬럼은 변형을 사용하지 않는다.
5. OR 보다는 AND를 사용한다.
6. HAVING 보다는 가급적 WHERE 절에서 데이터를 필터링 한다.
7. DISTINCT 는 가급적 사용하지 않는다.