간단명료

4.3 해시 조인 본문

친절한 SQL 튜닝/4장. 조인 튜닝

4.3 해시 조인

FeelGoood 2022. 3. 15. 22:14

4.3.1 기본 메커니즘

  1. Build 단계 : 작은 쪽 테이블(Build Input)을 읽어 해시 테이블(해시 맵)을 생성한다.
  2. Probe 단계 : 큰 쪽 테이블(Probe Input)을 읽어 해시 테이블을 탐색하면서 조인한다.
select /*+ ordered use_hash(c) */ *
from  사원 e, 고객 c
where c.관리사원번호   = e.사원번호
and   e.입사일자      >= '19960101'
and   e.부서코드       = 'Z123'
and   c.최종주문금액  >= 20000

해시 조인은 use_hash 힌트로 유도하며 위 SQL에 사용한 힌트는 사원 테이블 기준으로(ORDERED) 고객 테이블과 조인할 때 해시 조인 방식을 사용하라(use_hash)고 지시하고 있다.

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

    select *
    from 사원
    where 입사일자 >= '19960101'
    and 부서코드 = 'Z123'
  2. Probe 단계에 해당되는 고객 테이블을 읽어 Build 단계에서 만들어진 해시 테이블을 탐색한다. 즉, 관리사원번호를 해시 함수에 입력해서 반환된 값으로 해시 체인을 찾고, 그 해시 체인을 스캔해서 값이 같은 사원번호를 찾는다. Probe 단계는 NL조인과 다르지 않다.

    select *
    from 고객
    where 최종주문금액 >= 20000

4.3.2 해시 조인이 빠른 이유

Hash Area에 생성한 해시 테이블(=해시 맵)을 이용한다는 점만 다를 뿐 조인 프로세싱 자체는 NL 조인과 같다. 하지만 해시 테이블을 PGA영역에 할당하기 때문에, NL 조인은 Outer 테이블 레코드마다 Inner 쪽 테이블 레코드를 읽기 위해 래치 획득 및 캐시버퍼 체인 스캔 과정을 반복하지만, 해시 조인은 래치 획득 과정 없이 PGA에서 빠르게 데이터를 탐색하고 조인한다.
해시 조인도 Build Input 과 Probe Input 각 테이블을 읽을 때는 DB 버퍼캐시를 경유한다. 이때 인덱스를 이용하기도 한다.이 과정에서 생기는 버퍼캐시 탐색 비용과 랜덤 액세스 부하는 해시 조인도 피할 수 없다.
해시 테이블에는 조인 키값뿐만 아니라 SQL에 사용한 컬럼을 모두 저장한다.

대량 데이터 조인 시 해시 조인이 소트 머지 조인보다 빠른 이유

둘 다 오퍼레이션을 PGA에서 처리한다는 공통점을 갖는다. 성능 차이는 조인 오퍼레이션을 시작하기 전, 사전 준비작업에 있다.

  • 소트 머지 조인
    : 사전 준비작업은 '양쪽' 집합을 모두 정렬 후 PGA에 담는다.
  • 해시 조인
    : 사전 준비작업은 양쪽 집합 중 어느 '한쪽' 을 읽어 해시 맵을 만든다. 해시 조인은 둘 중 작은 집합을 해시 맵 Build Input으로 선택한다.

정리

해시 조인은 NL 조인처럼 조인 과정에서 발생하는 랜덤 액세스 부하가 없고, 소트 머지 조인처럼 양쪽 집합을 미리 정렬하는 부하도 없다. Build Input이 PGA 메모리에 담길 때, 즉 인메모리(In-Memory) 해시 조인일 때 가장 효과적인 이유가 바로 여기에 있다.


4.3.3 대용량 Build Input 처리, 4.3.4 해시 조인 실행계획 제어

page 288 참고


4.3.5 조인 메소드 선택 기준

일반적인 조인 메소드 선택 기준은 다음과 같다.

  1. 소량 데이터 조인 -> NL조인
  2. 대량 데이터 조인 -> 해시 조인
  3. 대량 데이터 조인 & 해시 조인으로 처리 불가(조인 조건식이 등치(=)조건이 아닐 때) -> 소트 머지 조인

소량과 대량의 차이는 단순히 데이터량의 많고 적음에 있지 않다. NL 조인 기준으로 '최적화했는데도' 랜덤 액세스가 많아 만족할만한 성능을 낼 수 없다면, 대량 데이터 조인에 해당한다.

수행빈도가 매우 높은 쿼리 시 조인 메소드 선택 기준은 아래와 같다.

  1. (최적화된) NL 조인과 해시 조인 성능이 같으면, NL 조인
  2. 해시 조인이 약간 더 빨라도 NL 조인
  3. NL 조인보다 해시 조인이 빠른 경우, 해시 조인(= 대량 데이터 조인 시 해시 조인)

2번의 이유는 NL 조인에 사용하는 인덱스는 (DBA가 Drop하지 않는 한) 영구적으로 유지하면서 다양한 쿼리를 위해 공유 및 재사용하는 자료구조다. 반면, 해시 테이블은 단 하나으 ㅣ쿼리를 위해 생성하고 조인이 끝나면 곧바로 소멸하는 자료구조다. 같은 쿼리를 100개 프로세스가 동시에 수행하면 해시 테이블도 100개가 만들어진다. 따라서 수행시간이 짧으면서 수행빈도가 매우 높은 쿼리(OLTP)를 해시 조인으로 처리하면 CPU와 메모리 사용률이 크게 증가한다.

결론

  1. 수행 빈도가 낮고
  2. 쿼리 수행 시간이 오래 걸리는
  3. 대량 데이터 조인 시
    해시 조인 메소드를 사용한다. 이 세 가지 조건은 배치 프로그램, DW, OLAP성 쿼리의 특징이기도 하다.
728x90
반응형

'친절한 SQL 튜닝 > 4장. 조인 튜닝' 카테고리의 다른 글

4.4 서브쿼리 조인  (0) 2022.04.03
4.2 소트 머지 조인  (0) 2022.03.13
4.1 NL 조인  (0) 2022.03.13
Comments