DBDBDEEP
4.3 해시조인 본문
HASH 조인 기본 매커니즘
Build 단계
- 작은 쪽 테이블(Build Input)을 읽어 해시 테이블(해시 맵)을 생성한다.
Probe 단계
- 큰 쪽 테이블(Probe Input)을 읽어 해시 테이블을 탐색하면서 조인한다.

① ===================================================

Build 단계
- 사원 데이터를 읽어 해시 테이블을 생성한다.
이 때 조인컬럼인 사원번호를 해시 테이블 키 값으로 사용한다.
'사원 번호'를 '해시함수'에 입력해서 '반환된 값' 으로 해시 체인을 찾고
그 해시 체인에 데이터를 연결한다.
- 해시 테이블은 PGA 영역에 할당된 Hash Area에 저장한다.
너무 크면 역시나 Temp Tablespace에 저장한다.

② ===================================================

Probe단계
- 고객 데이터의 '관리 사원번호'를 하나씩 읽어 앞서 생성한 해시테이블을 탐색한다.
함수에 입력해서 반환된 값으로 해시 체인을 찾고,
그 해시 체인을 스캔해서 값이 같은 사원번호를 찾는다.

NL & 해시 조인 특징
- 해시 테이블을 PGA 영역에 할당하기 때문에 빠르다.
- NL 조인은 Outer 테이블을 레코드마다 Inner 쪽 테이블 레코드를 읽기 위해
'래치 획득' 및 '캐시버퍼 체인 스캔과정을 반복'하지만
' 해시 조인은 래치 획득 과정이 없어' PGA에서 빠르게 데이터를 탐색하고 조인한다.
그러나 Build Input과 Probe Input에서 각 테이블을 읽을 때는 DB 버퍼캐시를 경유한다.
이 때 인덱스를 이용하기도 하는데 이 과정에서 생기는 비용은 해시조인도 피할 수 없음
- 해시 테이블에서는 조인 키값뿐만 아니라 SQL에 사용한 컬럼을 모두 저장한다!
- 해시 테이블을 만드는 비용이 수반되지만 '둘 중 작은 집합을 Build Input으로 선택하므로
부하가 대개 크지 않다.
> Build Input이 Hash Area보다 크게되면 Temp Tablespace를 쓸텐데
그럼에도 불구하고 대량 데이터 조인할 때는 일반적으로 해시 조인이 가장 빠르다.
대용량 Build Input인 경우

두 테이블 모두 커서 In-Memory 해시 조인이 불가할 경우 분할&정복 방식을 사용한다.
1. 조인하는 양쪽 집합 (조인 이의 조건절을 만족하는 레코드)의
조인 컬럼에 해시 함수를 적용하고
반환된 해시 값에 따라 동적으로 파티셔닝 한다.

2. 각 파티션 짝에 대해 조인을 수행
- 이 때, Build Input과 Probe Input은 독립적으로 결정된다.
'파티션 하기 전' 어느쪽이 작은 테이블이였는지는 상관없다.
- 파티션 별로 작은쪽을 Build Input으로 선택하고 해시테이블 생성한다.
그리고 반대쪽 파티션 로우를 하나씩 읽으면서 해시 테이블을 탐색한다.
- 모든 파티션 짝에 대한 처리를 마칠 때 까지 반복한다.


'위쪽 사원 데이터'로 해시 테이블을 생성한 후 '아래쪽 고객 테이블'에서 읽은 조인 키값으로 해시 테이블을 탐색하면서 조인
위에서는 use_hash 힌트만 사용해서 Build Input을 옵티마이저가 선택한다.
일반적으로 둘 중 카디널리티가 작은 테이블을 선택한다.
힌트를 쓰기
1. select /*+ leading(e) use_hash(c) */
-- 해시 조인에서 leading(e,c)로 쓴다면, 첫 번째 파라미터로 지정한 테이블은 무조건 Build Input으로 선택된다.
2. select /*+ ordered user_hash(c) */
3. swap_join_inputs 명령으로 build input을 명시적으로 선택할 수 있다.
select /*+ leading(T1,T2,T3) swap_join_inputs(T2) */ ...
이 경우에는 T2가 Build Input으로 설정되게 되고 실행계획은 아래와 같이 두가지가 나온다.

패턴 1을 2처럼 바꾸고 싶다면
아래와 같이 두가지 방법이 있다.
select /*+ leading(T1,T2,T3) swap_join_inputs(T3) */ ...
select /*+ leading(T1,T2,T3) swap_join_inputs(T2) swap_join_inputs(T3)/ ...
패턴 1을 2처럼 바꾸고 싶다면
select /*+ leading(T1,T2,T3) no_swap_join_inputs(T3) */ ...
Hash 조인을 쓰는 SQL문
1. 수행 빈도가 낮고
2. 쿼리 수행 시간이 오래 걸리고
3. 대량 데이터 조인 시
➜ 이 세가지 기준을 만족하는지 점검해야한다.
Hash 조인 특징
1. 조인 칼럼의 인덱스 유무가 조인 속도에 영향을 미치지 않는다.
2. 해시 조인은 각 테이블을 독립적으로 엑세스 하므로
테이블별 검색조건에 따라 전체 일량이 좌우 된다.
3. 조인 조건의 연산자가 '=' 등치 조건이 반드시 필요
4. NL 조인과 Sort Merge 조인의 단점을 개선 (과도한 랜덤 엑세스의 부담과 정렬의 부하를 제거함)
5. 해시 테이블 생성과 탐색에 많은 리소스를 사용하므로 OLTP 환경에서는 주의가 필요
'친절한 SQL 튜닝' 카테고리의 다른 글
| 서브쿼리 언네스팅 (0) | 2026.05.18 |
|---|---|
| 4.4 서브쿼리 (0) | 2026.05.18 |
| 4.2 소트 머지 조인 (0) | 2026.05.18 |
| 4.1 NL 조인 (0) | 2026.05.18 |
| LIKE/BETWEEN 조건 활용 (0) | 2026.05.18 |