개발자 키우기
2023. 12. 29. 21:03
오라클 힌트는 일반적으로 기술하였고 SQL Server 힌트는 오라클 힌트 뒤 , 쉼표 뒤에 넣어 기술했다.
1. 엑서스 경로
/*+ full(a) */ | a 테이블 전체 스켄 |
/*+ index(a a_index) */ | a 테이블의 a_index를 활용한 스켄 |
/*+ index_asc(a a_index) */ | a 테이블의 a_index를 오름차순으로 활용한 스켄 |
/*+ index_desc(a a_index) */ | a 테이블의 a_index를 내림차순으로 활용한 스켄 |
/*+ index_ffs(a) */ | a 테이블 FAST FULL SCAN (MultiBlock I/O) |
/*+ full(a) parallel(4) */ , option (maxdop 4) | a 테이블 Full Table Scan + 4개 병렬 프로세스 사용 |
/*+ index_ffs(a a_index) parallel(a a_index 4) */ , option (maxdop 4) |
a 테이블 Index Full Scan + 4개의 병렬 프로세스 사용 |
/*+ index_ss(a a_index) */ | a 테이블 Index skip scan 사용 |
/*+ no_index_ss(a a_index) */ | a 테이블 Index skip scan 사용 방지 |
/*+ index_combine(a a_index1 a_index2 */ | a 테이블 일반 인덱스를 비트맵 인덱스 구조를 만들어 Bit-Wise 오퍼레이션 수행(비트맵 인덱스인 경우 구조를 만들지 않고 바로 수행) |
/*+ index_join(a a_index1 a_index2) */ | a테이블의 두개의 인덱스를 가지고 각 범위스캔한 결과를 해시조인으로 테이블 액세스 없시 결과집합을 만듬 |
/*+ cluster(tableA) */ | tableA 테이블의 클러스터 인덱스를 사용하도록 유도 |
2. 조인
/*+ ordered use_nl(a) */ , option (force order) | FROM 절에 기술한 순서대로 NL 조인 수행 |
/*+ leading(a) use_nl(b) */ , option (force order, loop join) | a 테이블이 먼저 수행되고 NL 조인 수행 |
/*+ ordered use_merge(a) */ , option(force order, merge join) | FROM 절에 기술한 순서대로 머지 조인 수행 |
/*+ ordered use_hash(a) */ | FROM 절에 기술한 순서대로 해시 조인 수행 |
/*+ unnest */ | 서브쿼리를 풀어서 메인 쿼리에 포함되도록 수행 |
/*+ no_unnest */ | 서브쿼리를 그대로 둔 상태에서 필터 방식으로 최적화 수행 |
/*+ swap_join_inputs(a) */ | a 테이블을 Build Input 으로 설정 |
/*+ unnest nl_sj */ | Unnesting NL 세미 조인 |
/*+ unnest hash_sj */ | Unnesting Hash 세미 조인 |
/*+ unnest merge_sj */ | Unnesting Merge 세미 조인 |
/*+ unnest nl_aj */ | Unnesting Anti 조인 |
/*+ unnest hash_aj */ | Unnesting Hash Anti 조인 |
/*+ unnest merge_aj */ | Unnesting Merge Anti 조인 |
/*+ no_unnest push_subq */ | Pushing 서브쿼리 사용 |
/*+ leading(a@qb1) */ /*+ unnest qb_name(qb1) */ |
Unnesting 조인할때 쿼리 블록의 이름을 설정하고 명시하여 드라이빙 테이블을 선택 |
/*+ opt_param('_optimizer_native_full_outer_join', force') */ | Full outer join의 두번씩 테이블을 액세스하는 비효율을 줄여줌 |
/*+ eliminate_join(a) */ | 1:M에서 1인 a테이블의 결과를 읽지 않는 조인 제거 사용 |
/*+ no_eliminate_join(a) */ | 1:M에서 1인 a테이블의 결과를 읽지 않는 조인 제거 미사용 |
/*+ use_nl(a) no_nlj_batching(b) */ | inner 테이블인 b 테이블을 조인할때 배치기능 사용안함 (주로 inner 테이블의 정렬된 결과집합을 사용하기 위함) |
/*+ use_nl_with_index(a index_1) */ | a테이블의 index_1 인덱스를 사용하여 조인 |
/*+ nlj_prefetch(b) */ | inner 테이블 Prefetch 유도 |
/*+ no_nlj_prefetch(b) */ | inner 테이블 Prefetch 사용하지 않음 |
3. 최적화 목표
/*+ first_rows(a) */ , option(fastfirstrow) , option(fast 10) | a 만큼의 레코드만 읽음(sort 연산을 생략 할때도 사용) |
/*+ all_rows */ | 최종 결과까지 가장 비용이 적게 수행 |
/*+ result_cache */ | Result 캐시 사용 |
4. 쿼리 변환
/*+ use_concat */ | OR-Expansion 유도 |
/*+ no_expand */ | OR-Expansion 방지 |
/*+ rewrite */ | 쿼리 변환 유도 |
/*+ no_rewrite */ | 쿼리 변환 하지 않음 |
/*+ star_transformation */ | 스타형과 같은 중앙에 대형 테이블을 여러 작은 테이블과 조인할때 옵티마이저에게 최적의 쿼리 변환을 유도 |
/*+ no_star_transformation */ | 쿼리변환 유도 하지 않고 쿼리대로 수행 |
/*+ fact */ | 옵티마이저에게 이 테이블이 웨어하우스의 사실 테이블이라 알려줌 |
/*+ no_fact */ | 옵티마이저에게 사실 테이블이라 알려주지 않음 |
5. 병렬 처리
/*+ pq_distribute(inner, none, none) */ | Full-Partition Wise Join 유도(양쪽 테이블 모두 조인 칼럼에 대해 같은 기준으로 파티셔닝 되어 있어야함) |
/*+ pq_distribute(inner, partition, none) */ | Partition-Partition Wise Join 유도(inner 테이블이 조인 키 칼럼에 대해 파티셔닝이 되어 있어야함) |
/*+ pq_distribute(inner, none , partition) */ | Partition-Partition Wise Join 유도(outer테이블이 조인 키 칼럼에 대해 파티셔닝이 되어 있어야함) |
/*+ pq_distribute(inner, hash, hash) */ | 조인 키 칼럼을 해시 함수에 적용하고 반환된 값을 기준으로 양쪽 테이블을 동적으로 파티셔닝 수행 |
/*+ pq_distribute(inner, broadcast , none) */ | outer 테이블을 Broadcast 수행 |
/*+ pq_distribute(inner, none, broadcast) */ | inner 테이블을 Broadcast 수행 |
/*+ parallel_index(index_1 4) */ | index_1의 사용하여 4개의 병렬처리로 인덱스를 생성하거나 스켄하도록 유도 |
/*+ no_parallel_index(index_1 4) */ | index_1의 사용하여 4개의 병렬처리로 인덱스를 생성하거나 스켄하도록 유도 하지 않음 |
6. Lock 관련
, with (holdlock) | 공유 Lock 사용 |
, with (updlock) | 갱신 Lock 사용 |
7. 기타
/*+ batch_table_access_by_rowid(a) */ | 배치 I/O 사용 |
/*+ push_pred */ | 조인 조건 pushdown 사용 |
/*+ no_push_pred */ | 조인 조건 pushdown 사용 하지 않음 |
/*+ driving_site(b) */ | 조인 연산에서 조인 조건을 먼저 처리 되는 테이블을 정함 |
/*+ meterialize */ | 임시테이블을 생성하여 with 구문 사용 |
/*+ inline */ | 임시테이블을 생성하지 않고 with 구문 사용 |
/*+ cardinality(a 10) */ | a 테이블의 카디널리티가 10이라고 알려줌 |
/*+ cpu_costing */ | I/O + CPU 비용 모델 사용 |
/*+ no_cpu_costing */ | I/O 비용 모델 사용 |
/+ '_optimizer_push_pred_cost_based', 'false') */ | 비용기반 쿼리 변환 방식 끄기 |
/*+ append */ | 대량 INSERT시 데이터 잠금 최소화 |
/*+ no_append */ | append 힌트 사용안함 |
/*+ cache */ | 데이터를 캐시하여 사용함 |
/*+ no_cache */ | 데이터를 캐시하지 않음 |
/*+ qb_name(a) */ | a라는 하나의 쿼리블록을 캐시하여 사용 |
/*+ push_subq */ | 하위쿼리를 상위 쿼리로 pushup |
/*+ no_push_subq */ | 하위쿼리를 상위 쿼리로 pushup하지 않음 |
ALTER SYSTEM SET cursor_sharing_exact = FORCE; | 동일한 SQL 문이 서로 다른 리터럴 값으로 실행될 때에도 동일한 커서를 공유 |
/*+ DYNAMIC_SAMPLING(4) */ | 통계정보가 부족할때 4개의 샘플 데이터를 추출하여 데이터 분포를 추정하여 실행계획 생성 |
/*+ MODEL_MIN_ANALYSIS */ | 모델 클로즈 문의 분석에서 최소한의 분석만 수행 |
/*+ OPT_DYN_SAMP */ | 동적 샘플링 수행 |
- 참고 서적 : SQL 전문가 가이드 -
- 참고 서적 : 오라클 성능 고도화 원리와 해법 1, 2 -