ex) /*+ INDEX(A SI_COL1) INDEX(B SI_COL2) */
기본구조
/*+ INDEX(테이블명 인덱스명) */
SELECT /* INDEX(A SI_고객ID) */
고객명, 연락처, 주소
FROM 고객 A
WHERE 고객ID = '1234'
-- INDEX(A SI_고객ID) : A 테이블을 SI_고객ID 인덱스를 이용해 조회
* SI : Single Index, MI : Multi Index
(인덱스명을 반드시 이걸로 지을 필요는 없음)
SELECT /*+ INDEX(A) */
고객명, 연락처, 주소
FROM 고객 A
-- INDEX(A) : A 테이블을 인덱스를 이용해 조회, 어떤 인덱스를 이용할지는 옵티마이저가 결정
SELECT /*+ ordered use_nl(B) */
-- 생략
FROM 사원 A
, 고객 B
-- oredred : FROM 절에 나열된 순서로 조인
-- use_nl(B) : B를 NL방식으로 조인
SELECT /*+ ordred use_nl(B) use_nl(C) use_hash(D) */
-- 생략
FROM A, B, C, D
-- ordered : FROM 절에 나열된 순서로 조인
-- use_nl(B) : B를 NL방식으로 조인
-- use_nl(C) : C를 NL방식으로 조인
-- use_hash(D) : D를 해시방식으로 조인
SELECT /*+ leading(B,D,A,C) use_nl(D) use_nl(A) use_hash(C) */
-- 생략
FROM A, B, C, D
-- leading(B,D,A,C) : 괄호에 명시한 순서로 조인
-- use_nl(D) : D를 NL방식으로 조인
-- use_nl(A) : A를 NL방식으로 조인
-- use_hash(C) : C를 해시방식으로 조인
SELECT /*+ leading(B) */
-- 생략
FROM A, B, C
-- leading(B) : 조인의 시작테이블만 B로 고정, 나머지 순서는 옵터마이저가 결정
SELECT /*+ use_nl(A,B,C) */
-- 생략
FROM A, B, C
-- use_nl(A,B,C) : 괄호의 테이블을 nl방식으로 조인, 조인순서는 옵티마이저가 결정
SELECT /*+ use_hash(a b) */
-- 생략
FROM a, b
-- a와 b를 해시방식으로 조인, Build Input은 옵티마이저가 선택(각각 조건절로 거른 후 테이블의 카디널리티가 더 작은 쪽을 선택) _282p~285p 참고
-- *Build Input: 해시맵으로 만들 테이블 _해시 조인 매커니즘 참고
/*+ ordered use_hash(b) */
FROM a, b
/*+ leading(a) use_hash(b) */
FROM a, b
/*+ leading(a) use_hash(b) swap_join_inputs(b) */
FROM a, b
* 3개 이상 테이블 해시조인, Build Input 지정 방법 _291p~296p 참고
SELECT a.학생번호, a.학생이름
FROM 학생 a
WHERE a.입학년도 >= 2025
AND EXISTS (
SELECT /*+ unnest nl_sj */
1
FROM 학생
WHERE 학생번호 = a.학생번호
AND 입학년도 >= 2024
)
-- unnest : 서브쿼리를 unnest를 통해 조인
-- nl_sj : 해당 쿼리블록이 어딘가(메인쿼리등)에서 조인될 때, 조인방법으로 nl조인을 사용
- QB_NAME 힌트 사용 예시
QB_NAME : 쿼리블록의 이름을 지정SELECT /*+ leading(학생@subq) use_nl(a) */ a.학생번호, a.학생이름 FROM 학생 a WHERE a.입학년도 >= 2025 AND EXISTS ( SELECT /*+ qb_name(subq) unnest*/ 1 FROM 학생 WHERE 학생번호 = a.학생번호 AND 입학년도 >= 2024 ) -- (학생@subq) : subq라는 쿼리블록 안의 학생테이블을 의미 -- leading : 서브쿼리를 unnest를 통해 join으로 변환했기 때문에, 조인힌트인 leading 사용가능 -- use_nl : 이 쿼리의 경우, 서브쿼리 안이 아닌 메인쿼리에서 조인방식 선택 (어디서 하든 자유)
SELECT a.회사명
, b.입금일자
FROM 회사 a
, (SELECT /*+ merge */
입금일자
FROM 입금
) b
where a.회사번호 = b.회사번호
-- 뷰를 메인쿼리와 통합(한 상태에서 옵티마이저가 최적화 수행) _4.4.1절(서브쿼리 변환이 필요한 이유), 4.4.3절(뷰와 조인) 참고
참고) 친절한 SQL 튜닝 - 조시형