힌트 사용
힌트 란?
- 옵티마이저는 모든 실행 계획을 수행 시 고려할 수 없기 때문에 일부 실행 계획을 사전에 제외시킨다
- 옵티마이저의 수행 환경을 바꾸거나, 특정 기능을 활성화/비활성화 한다
- 일반적으로는 고려할 실행 계획의 범위를 고정시키는게 목적이다
힌트 지정
- DELETE, INSERT, UPDATE, SELECT, MERGE 단어 바로 뒤에 사용
- /*\+ HINT \*/
- 힌트의 문법 오류는 SQL 오류를 발생시키지 않고 주석으로 간주 됨
힌트의 범주
> 저자가 선호하는 분류이다
1) 초기화 파라메터 힌트
- 시스템/세션 레벨에서 설정 된 이니셜 파라메터의 설정값을 변경
- ex> first_rows ...
2) 쿼리 변환 힌트
- 최적화 시 쿼리 변환 방법 제어
- ex> no_expand, no_merge ...
3) 엑세스 패스 힌트
- 테이블 엑세스 방법 제어
- ex> full, index ...
4) 조인 힌트
- 조인 방법 및 순서 제어
- ex> ordered, leading ...
5) 병렬 처리
- 병렬의 사용 여부, 어떻게 사용할지 제어
- ex> parallel, pq_distribute ...
6) 기타
힌트의 효력
- 초기화 파라메터는 일반적으로 전체 SQL 구문에 대해 유효하다
- 대부분의 다른 힌트는 일반적으로 단일 쿼리 블럭에서만 유효하다
- 글로벌 힌트를 사용 시 . 을 이용하여 다른 쿼리블럭을 지정, 참조 가능하다
with emps as (
select dept_no, count(*) as cnt
from emp
group by deptno
)
select /*+ full(dept) full(emps.emp) */
dept.dname, emps.cnt
from dept, emps
where dept.deptno = emps.deptno
- qb_name 을 사용한 쿼리 블럭 이름을 명시적으로 사용하는 것이 효율적이다
with emps as (
select /*+ qb_name(sub) */ dept_no, count(*) as cnt
from emp
group by deptno
)
select /*+ qb_name(main) full(@main dept) full(@sub emp) */
dept.dname, emps.cnt
from dept, emps
where dept.deptno = emps.deptno
- 사용자가 지정하지 않아도 시스템에서 자동으로 쿼리 블럭 이름을 생성하며, 접두어 + 알파벳/숫자 형식이다
사용 시기
- 옵티마이저가 효율적인 실행 계획을 자동으로 만들지 못할 때 사용한다
- 불가피한 경우가 아니면 영구적인 방법으로 힌트를 고려하지 말자
주의점
- 통계와 엑세스 구조가 어느정도 바뀌더라도 안정적으로 유지되게 힌트를 사용해야 한다
- 일부 문법을 체크하는 특이한 힌트도 있다 ex> change_dupkey_errpr_index ...
- 10132 이벤트 트레이스로 힌트가 잘못되지 않은 문법으로 인식 되었는지 판단 가능하다
- 테이블 별칭을 사용할 경우 테이블명 대신에 별칭을 힌트에 언급해야 한다
- 동일 힌트라도 다른 DB 버전에서는 다르게 동작할 수 있다
- 세션 레벨에서 _optimizer_ignore_hints = true 로 설정 후 처음부터 다시 검증하는게 가장 바람직
- 뷰는 다양한 상황에서 사용되므로 뷰 내부에 힌트를 쓸 경우는 주의 필요