두 단계로 진행된다.
두 테이블이 모두 대용량 테이블이라 인메모리 해시조인이 불가능하다면?
이럴때 2단계로 나눠 분할-정복 (Divide & Conquer) 방식을 사용한다.
조인하는 양쪽 집합의 조인 컬럼에 해시함수를 적용하고, 반환된 해시 값에 따라 동적으로 파티셔닝 한다.
독립적으로 처리할 수 있는 여러개의 작은 서브 집합으로 분할함으로서 파티션짝을 생성하는 단계
해시 조인 실행계획을 제어할 때 아래와 같이 use_hash 힌트를 사용한다.
SELECT /*+ use_hash(e c) */
e.사원번호, e.사원명, e.입사일자
, c.고객번호, c.고객명, c.전화번호, c.최종주문금액
FROM 사원 e, 고객 c
WHERE c.관리사원번호 = e.사원번호
AND e.입사일자 >= ‘19960101’
AND e.부서코드 = ‘Z123’
AND c.최종주문금액 >= 2000
SELECT /*+ leading(e) use_hash(c) */ -- 또는 ordred use_hash(c)
e.사원번호, e.사원명, e.입사일자
, c.고객번호, c.고객명, c.전화번호, c.최종주문금액
FROM 사원 e, 고객 c
WHERE c.관리사원번호 = e.사원번호
AND e.입사일자 >= ‘19960101’
AND e.부서코드 = ‘Z123’
AND c.최종주문금액 >= 2000
아래와 같이 swap_join_inputs 힌트로 Build Input을 직접 선택하는 방법도 있다.
SELECT /*+ use_hash(e c) swap_join_inputs(e) */
e.사원번호, e.사원명, e.입사일자
, c.고객번호, c.고객명, c.전화번호, c.최종주문금액
FROM 사원 e, 고객 c
WHERE c.관리사원번호 = e.사원번호
AND e.입사일자 >= ‘19960101’
AND e.부서코드 = ‘Z123’
AND c.최종주문금액 >= 2000
해시조인이 빨라도 단점이 있다. 수행빈도가 높은 쿼리에 대해 위험하다.
수행빈도가 매우 높은 쿼리에 대한 기준
왜 2번처럼 해시 조인이 NL 보다 빨라도 NL 조인을 써야 하는가?
- NL조인에 사용되는 인덱스는 영구적으로 유지하면서 다양한 쿼리를 위해 공유 및 재사용하는 자료구조이다.
- 해시 테이블은 단 하나의 쿼리를 위해 생성하고 사용이 끝나면 소멸하는 자료구조이다.
- 해시 조인을 사용하면 CPU와 메모리 사용률을 크게 증가시킨다.
- 해시 맵을 만드는 과정에서 여러 래치 경합도 발생!
해시 조인이 사용되는 3가지 조건
- 수행 빈도가 낮고
- 쿼리 수행 시간이 오래 걸리는
- 대량의 데이터를 조인할 때.