해시 조인

이재철·2021년 10월 16일
0

SQL

목록 보기
10/11
  • 트 머지 조인은 항상 양쪽 테이블을 정렬하는 부담이 있는데, 해시 조인은 그런 부담도 없다.

기본 메커니즘

select /* ordered use_hash(c) */
	e.사원번호, e.사원명, e.입사일자
    c.고객번호 , c.고객명, c.전화번호, c.최종주문금액
from 사원 e, 고객 c
where c.관리사원번호 = e.사원번호
and e.입사일자 >= '19960101'
and e.부서코드 = 'Z123'
and c.최종주문금액 >= 20000
  1. Build 단계
    - 작은 쪽 테이블을 읽어 해시 테이블을 생성한다.

    아래 조건에 해당하는 사원 데이터를 읽어 해시 테이블을 생성한다.
    사원번호를 해시 함수에 입력해서 반환된 값으로 해시 체인을 찾고, 그 해시 체인에 데이터를 연결한다.
    해시 테이블은 PGA 영역에 할당된 Hash Area에 저장한다.

    select e.사원번호, e.사원명, e.입사일자
    from 사원 e
    where e.입사일자 >= '19960101'
    and e.부서코드 = 'Z123'
  2. Probe 단계
    - 큰 쪽 테이블을 읽어 해시 테이블을 탐색하면서 조인한다.

    • 아래 조건에 해당하는 고객 데이터를 하나씩 읽어 앞서 생성한 해시 테이블을 탐색한다.
    • 즉, 관리사원번호를 해시 함수에 입력해서 반환된 값으로 해시 체인을 찾고, 그 해시 체인을 스캔해서 값이 같은 사원번호를 찾는다.
    select c.고객번호 , c.고객명, c.전화번호, c.최종주문금액, c.관리사원번호
    from 고객 c
    where c.최종주문금액 >= 20000
    • Build 단계에서 사용한 해시 함수를 Probe 단계에서도 사용하므로 같은 사원번호를 입력하면 같은 해시 값을 반환한다.
    • NL 조인과 다르지 않다.
  • use_hash 힌트 사용

해시 조인이 빠른 이유

  • Hash Area에 생성한 해시 테이블을 이용한다는 점만 다를 뿐 해시 조인도 조인 프로세싱 자체는 NL 조인과 같다.
  • NL 조인보다 빠른 이유
    • 해시 테이블을 PGA 영역에 할당하기 때문이다.
    • 래치 획득 과정 없이 PGA에서 빠르게 데이터를 탐색하고 조인한다.
  • 해시 조인과 소트 머지 조인의 성능 차이는 조인 오퍼레이션을 시작하기 전, 사전 준비 작업에 기인한다.
    • 소트 머지 조인에서 사전 준비작업은 '양쪽' 집합을 모두 정렬해서 PGA에 담는 작업
    • 해시 조인에서 사전 준비작업은 양쪽 집합 중 어느 '한쪽'을 읽어 해시 맵을 만드는 작업
  • 해시 조인은 NL조인처럼 조인 과정에서 발생하는 랜덤 액세스 부하가 없고, 소트 머지 조인처럼 양쪽 집합을 미리 정렬하는 부하도 없다.

대용량 Buil Input 처리

  • 분할 정복 방식
  1. 파티션 단계
    • 조인하는 양쪽 집합(조인 이외 조건절을 만족하는 레코드)의 조인 컬럼에 해시 함수를 적용하고, 반환된 해시 값에 따라 동적으로 파티셔닝한다.
    • 독립적으로 처리할 수 있는 여러 개의 작은 서브 집합으로 분할함으로써 파티션 짝을 생성하는 단계다.
  2. 조인 단계
    • 파티션 단계를 완료하면 각 파티션 짝에 대해 하나씩 조인을 수행한다.
    • 각각에 대한 Build Input과 Probe Input은 독립적으로 결정된다.
    • 각 파티션 짝별로 작은 쪽을 Build Input으로 선택하고 해시 테이블을 생성한다.
    • 해시 테이블을 생성하고 나면 반대쪽 파티션 로우를 하나씩 읽으면서 해시 테이블을 탐색한다.
    • 모든 파티션 짝에 대한 처리를 마칠 때까지 이 과정을 반복한다.

해시 조인 실행꼐획 제어

  • 해시 조인 실행계획을 제어할 때 use_hash 를 사용
  • use_hash 만 사용할 경우 옵티마이저가 Build Input을 선택하는데, 일반적으로 둘 중 카디널리티가 작은 테이블을 선택한다.
  • 조인 대상 테이블이 두 개라면 leading이나 ordered 힌트를 사용하여 Build Input을 직접 선택할 수 있다.
  • swap_join_inputs 힌트로 Build Input을 명시적으로 선택할 수도 있다.

세 개 이상 테이블 해시 조인

  • 조인하는 테이블이 몇 개든, 조인 연결고리를 따라 순방향 또는 역방향으로 leading 힌트에 기술한 후, Build Input으로 선택하고 싶은 테이블을 swap_join_inputs 힌트에 지정해 주면 된다.
  • Build Input으로 선택하고 싶은 테이블이 조인된 결과 집합이어서 swap_join_inputs 힌트로 지정하기 어렵다면, no_swap_join_inputs 힌트로 반대쪽 Probe Input을 선택해 주면 된다.

조인 메소드 선택 기준

  • 일반적인 조인 메소드 선택 기준

    소량 데이터 조인할 때 : NL 조인
    대량 데이터 조인할 때 : 해시 조인
    대량 데이터 조인인데 해시 조인으로 처리할 수 없을 때, 즉 조인 조건식이 등치 조건이 아닐 때 : 소트 머지 조인

  • 수행빈도가 매우 높은 쿼리에 대한 기준

    (최적화된) NL 조인과 해시 조인 성능이 같으면: NL 조인
    해시 조인이 약간 더 빨라도: NL 조인
    NL 조인보다 해시 조인이 매우 빠른 경우: 해시 조인

  • 왜 NL 조인을 선택해야 할까?

    NL 조인에 사용하는 인덱스는 영구적으로 유지하면서 다양한 쿼리를 위해 공유 및 재사용하는 자료구조다.
    반면, 해시 테이블은 단 하나의 쿼리를 위해 생성하고 조인이 끝나면 곧바로 소멸하는 자료구조다.
    따라서 수행시간이 짧으면서 수행빈도가 매우 높은 쿼리를 해시 조인으로 처리하면 CPU와 메모리 사용률이 크게 중가한다. 해시 맵을 만드는 과정에 여러 가지 래치 경합도 발생한다.

  • 해시 조인은 아래 세가지 조건을 만족하는 SQL문에 주로 사용

    1. 수행 빈도가 낮고
    2. 쿼리 수행시간이 오래 걸리는
    3. 대량 데이터 조인할 때

0개의 댓글