1. HASH JOIN 이란?
HASH 조인은 조인될 두 테이블 중 하나를 해시 테이블로 선정하여 조인될 테이블의 조인 키 값을 해시 알고리즘으로 비교하여 매치되는 결과값을 얻는 방식이다.
동작 방식
1. 둘 중 작은 집합(Build Input)을 읽어 Hash Area에 해시 테이블을 생성한다. (해시 함수에서 리턴 받은 버킷 주소로 찾아가 해시 체인에 엔트리를 연결)
- 작은 테이블에서 해시 테이블을 만드는 이유는 해시 테이블은 DBMS의 워킹 메모리에 저장되므로 조금이라도 작은 것이 효율적이기 때문이다.
2. 반대쪽 큰 집합(Probe Input)을 읽어 해시 테이블을 탐색하면서 JOIN 한다.
3. 해시 함수에서 리턴 받은 버킷 주소로 찾아가 해시 체인을 스캔하면서 데이터를 찾는다.
2. 특징
- Nested Loops에서 적절한 구동 테이블(상대적으로 충분히 작은)이 존재하지 않는 경우 유용합니다.
- Nested Loops의 단점에서 구동 테이블로 사용할만한 작은 테이블은 있지만, 내부 테이블에서 히트되는 레코드 수가 너무 많은 경우
- Nested Loops의 내부 테이블에 인덱스가 존재하지 않는 경우
- HASH JOIN은 '=' 비교를 통한 조인에서만 사용될 수 있다. 주로 많은 양의 데이터를 조인해야 하는 경우에 주로 사용된다.
- 한마디로 말하면 Nested Loops가 효율적으로 작동하지 않는 경우의 차선책이 Hash이다.
- 배치에서 사용하면 좋은 방법.
- 수행 빈도가 높은 OLTP 환경에서 HASH JOIN으로 풀리면 CPU와 메모리 사용량이 많아져서 성능이 안좋아질 수 있음. 다른 방법으로 풀릴 수 있게 유도
-> 대규모 테이블들을 결합할 때 적합. 정렬되어 있다면 Merge Sort 그렇지 않으면 Hash가 적합하다.
3. 단점
- 초기에 해시 테이블을 만들어야 하므로, Nested Loops에 비해 소비하는 메모리 양이 많음
- Hash 결합은 반드시 양쪽 테이블의 레코드를 전부 읽어야 하므로, 테이블 풀 스캔이 사용되는 경우가 많다. 테이블의 규모가 굉장히 크다면, 이런 풀 스캔에 걸리는 시간도 고려해야 한다.
4. HASH JOIN의 사용처
1. JOIN 컬럼에 적당한 인덱스가 없어 NL JOIN이 비효율적일 때
2. JOIN Access량이 많아 Random Access 부하가 심하여 NL JOIN이 비효율적일 때
3. Sort Merge Join을 하기에는 두 테이블이 너무 커 Sort 부하가 심할 때
4. 수행빈도가 낮고 쿼리 수행 시간이 오래 걸리는 대용량 테이블을 JOIN 할 때
5. HASH JOIN의 성능 개선 포인트
- HASH TABLE을 만드는 과정을 효율화 한다.
- HASH TABLE로 만들 Build Input이 Hash Area에 담길 정도로 충분히 작아야 하며 Build Input 해시 키 칼럼에 중복 값이 거의 없어야 효율적인 동작을 기대할 수 있습니다.
- CPU의 성능을 향상한다.
- 충분한 PGA 메모리 확보
- Hash Area는 PGA 메모리에 할당되는데 Build Input이 HASH_AREA_SIZE를 초과하게 되면 가장 큰 순서대로 Hash Bucket이 Temporary Table Space로 내려가서 구성된다. 디스크로 내려간 Hash Bucket에 변경이 일어날 때마다 디스크 I/O가 발생하게 되어 성능이 현저하게 저하된다.
HASH_AREA_SIZE
HASH JOIN에 사용되는 최대 메모리 SIZE를 지정하는 설정값이다. Hash Join에서 사용되는 해쉬 메모리 크기(HASH_AREA_SIZE)의 기본 값은 SORT_AREA_SIZE의 2배이다. 9i 이상에서 값을 지정하는 것을 권장하지 않고, PGA_AGGREGATE_TARGET parameter 사용을 권장한다.
REFERENCE
https://coding-factory.tistory.com/758?category=990785
'Database' 카테고리의 다른 글
[Database] SORT MERGE JOIN 최적화 (0) | 2021.11.14 |
---|---|
[Database] 데이터베이스 I/O 원리 및 최적화 (0) | 2021.11.14 |
[Database] Nested Loop 최적화 (2) | 2021.11.14 |
[Database] 정규화 정리 (0) | 2021.10.24 |
Statement와 PreparedStatement (0) | 2021.10.17 |