[SQL-TUNING] 조인 튜닝 - HASH Join

­이승환·2022년 4월 3일
0

Sql-tuning

목록 보기
7/8

Hash Join


  • NL 조인은 인덱스 구성에 따라 속도차이가 심하게 나타난다.
  • 인덱스를 아무리 완벽하게 구사했더라도, 랜덤 I/O 때문에 대량의 데이터 처리에 불리하고, 버퍼캐시 히트율에 따라 들쭉날쭉한 성능을 보인다.
  • 소트 머지 조인과 해시 조인은 조인 과정에서 인덱스를 이용하지 않기 때문에 대량 데이터 조인할 때, 빠르고 일정한 성능을 보여준다.

기본 메커니즘

  • 2단계로 구성되어 있다.

    1. BUILD : 데이터나 카디널리티가 작은 테이블을 읽어 해시 테이블을 완성한다.
    2. PROBE : 다른 테이블을 읽어서 해시 테이블을 탐색하면서 조인한다.
  • BUILD

    • 조건에 해당하는 데이터를 읽어서 해시 테이블을 생성한다.
    • 조인컬럼을 해시 테이블의 키 값으로 사용한다. (해시 자료구조에 대해서 모른다면 확인해보자)
    • 해시는 체이닝 구조로 구성되어 있다.
    • 해시 테이블은 PGA 에 저장되고, 모자라면 TEMP 메모리에 저장된다.
  • PROBE

    • 상대적으로 적은 테이블을 탐색하면서 조건절에서 활용한 칼럼(키)을 이용해서 PGA에서 탐색한다.
    • 만약 해시테이블에서 찾으면 조인에 성공, 없다면 실패한 것이다. 상대적으로 빠르다.
  • OUTER TABLE(해시테이블이 아닌 상대적으로 큰 테이블) 은 NL 조인과 실행계획은 동일하다. 다른 점은 해시테이블을 구성한다는 점이 다르다.

해시 조인이 빠른 이유?

  • 소트 머지 조인과 마찬가지로, PGA 영역을 할당하기 때문에 빠르다.
  • NL 조인의 경우, OUTER 테이블 레코드 마다 INNER 테이블 접근을 위해 버퍼 래치획득과정과 체인 스캔과정을 거친다. 하지만 해시조인은 래치 획득 과정이 없이 PGA영역을 이용하기 때문에 빠른 것이다.
  • 해시 조인도 BUILD INPUT, PROBE INPUT 각 테이블을 읽을 떄는 DB 버퍼캐시를 경유한다. 이 때 인덱스를 이용하기도 한다. 이 과정에서 생기는 버퍼캐시 탐색 비용과 랜덤 액세스 부하는 어쩔 수 없다.
  • 해시 테이블을 구성한다고 해서 일반적인 인덱스처럼 ROWID만 가지고 있다고 착각하는 경우가 있는데, 그것이 아니라 PGA에 진짜로 테이블을 만들고, 해시 체이닝을 통해 해당 메모리 주소를 바로 찾는 것이라고 이해하는 것이 빠르다.
  • 소트 머지 조인의 경우, OUTER && INNER 테이블 모두 정렬 이 후, PGA 영역에 저장하여 1대1 대응하는 머징작업을 진행하지만, 해시 조인의 경우 카디널리티가 낮거나, 작은 테이블을 기준으로 해시테이블 생성작업을 진행하기 때문에 해시 조인이 상대적으로 더 빠르다고 한다.

대용량 Build Input 처리

  • 만일 해시테이블로 생성하려고 하는 테이블 데이터가 매우 큰 경우에는, Divide & Conquer 방식으로 진행한다.

  • 1단계 : 파티션

    • 조인하는 양쪽 집합의 조인 컬럼에 해시 함수를 적용하고, 반환된 해시 값에 따라 동적으로 파티셔닝 한다. (테이블 행 값들을 서로 매칭해서 나눈다.)
  • 2단계 : 조인 단계

    • 각 파티션 pair에 대해 하나씩 조인을 수행한다. 이때, 각각에 대한 build input && Probe input 과정은 독립적으로 결정한다.
    • 파티션 별로 데이터 양이 적은 쪽을 해시 테이블로 구성한다는 의미이다. (독립적 해시조인 진행)

해시조인 실행계획 제어

  • 앞서 언급한것 처럼, 조건절 컬럼의 카디널리티가 적으면서 테이블 전체 사이즈가 작은 테이블을 해시 테이블로 활용한다.
  • 하지만 사용자가 직접 명시적으로 설정 할 수 있다.
$ select /*leading(e) use_hash(c)*/ -- 또는 ordered use_hash(c) ...

조인 메소드 선택 기준

  • 지금까지 NL, Sort merge, hash 조인에 대해서 알아봤다.

  • 무엇을 기준으로 사용할 조인 함수를 활용하면 좋을까?

  • 해결책은 아래와 같다.

  • 소량 데이터 조인할 때

    NL 조인

  • 대량데이터 조인이면서 조인 조건식이 동치인 경우

    HASH

  • 대량데이터 조인이면서 조인 조건식이 동치가 아닌 경우

    Sort Merge

  • NL 조인과 해시 조인 성능이 같으면

    NL 조인

  • 해시 조인이 약간 더 빠른경우(성능차이가 미비)

    NL 조인

  • NL 조인보다 해시 조인이 빠른경우

    HASH 조인

  • 해시 조인이나 소트머지의 경우 각 쿼리 실행마다 PGA || TEMP 영역을 위해 독닥전인 자료구조 생성 후 삭제하는 로직이다. 따라서 CPU나 메모리 사용률이 크게 증가한다.

  • 개발자는 항상 PROS & CONS와 관해서 TRADE OFF를 항상 해야 한다는 것을 잊으면 안 된다.

profile
Mechanical & Computer Science

0개의 댓글