Data Base/SQL 튜닝

hash join

잇꼬 2024. 2. 23. 09:01
728x90
반응형
SMALL

■ hash join 

1. 정의

- 대량의 데이터에 대한 조인 연산에서 효과적으로 사용되는 조인 알고리즘 중 하나.

- Nested loop join의 랜덤 액세스 부다과 Sort Merge Join의 정렬 작업 부담을 피하기 위해서 사용됨. 

2. 동작원리

- 작은 쪽의 집합을 Build Table로 선택하여 Hash Table 을 생성. 

- 큰 쪽의 집합을 Probe 하여 Hash Table 을 탐색하여 조인 수행.

- Hash Table은 Hash Area Size로 지정된 메모리 영역에 생성.

3. 조인 제약 조건

- Equal(=) 조건만 가능: Hash Join은 등호 조건에서만 사용 가능하며, 일반적으로 등호 조건에서 성능이 가장 좋음.

4. 효과적인 경우

- 작은 집합이 Build Table로 생성될 때.
- Hash Key에 중복 값이 거의 없는 경우.
- Hash Key 충돌이 발생하지 않는 경우

5. 설정 매개변수

- `hash_area_size`: Hash Table이 생성되는 메모리 공간 크기를 지정.

6. 장단점 

1) 장점

- 대량의 데이터에 효과적.

- Random 액세스나 정렬 작업 부담이 적음

2) 단점

- Equal(=) 조건에만 사용 가능.

- 작은 집합의 크기와 Hash Key의 품질에 민감.


<hr sess>

select /*+ gather_plan_statistics leading(d,e) use_hash(e) */ 
        d.depatment_id, d.department_name, e.employee_id, e.last_name, e.salary
from departments d, employees e
where d.department_id = e.department_id;

 

#) 실행 계획 확인

select * from table(dbms_xplan.display_cursot(null, null, 'allstats last'));

☆ hash_area_size : PGA (Program Global Area) 내에 위치한 메모리 영역으로, Hash Join에서 사용되는 Hash Table이 생성되는 공간 크기이다.

▷ probe: sql문을 scan 한다.

- Probe는 Hash Join에서 큰 쪽의 테이블을 스캔하고 Hash Table을 탐색하는 단계

- 큰 테이블의 각 행은 Hash Key를 기반으로 해시 함수를 적용하고, 해당 해시 버킷을 찾아가며 Hash Table을 탐색한다.
- 조인 조건을 확인하면서 일치하는 행을 찾아내는 과정이다.

▷빌드테이블과 프로브 테이블

- Hash Join에서 작은 테이블을 Build Table로 지정하고 큰 테이블을 Probe Table로 지정한다.
- Build Table은 작은 테이블로, Hash Table을 생성하여 해시 버킷에 행을 저장한다.
- Probe Table은 큰 테이블로, Hash Key를 계산하여 해당 버킷을 찾아가며 Hash Table을 탐색한다.

 

※ 요약

- `hash_area_size`는 PGA 내의 Hash Join에 사용되는 Hash Table의 메모리 크기를 지정하는 매개변수이다.
- Hash Join은 Build Table과 Probe Table로 나누어지며, 작은 테이블을 Build Table로 선택하는 것이 성능 향상에 도움이 된다.
- 빌드 테이블의 중요성은 Hash Table의 생성 및 해시 조인 성능에 큰 영향을 미친다.

 


#1) 기본 use_hash() 사용

<hr sess>

select /*+ gather_plan_statistics leading(d,e) use_hash(e) */ 
        d.department_id, d.department_name, e.employee_id, e.last_name, e.salary
from departments d, employees e
where d.department_id >= e.department_id;

 

#) 실행 계획 확인

select * from table(dbms_xplan.display_cursot(null, null, 'allstats last'));

 


 

#2) 빌드 테이블 바꿔보기

<hr sess>

select /*+ gather_plan_statistics leading(e,d) use_hash(e) */ 
        d.department_id, d.department_name, e.employee_id, e.last_name, e.salary
from departments d, employees e
where d.department_id = e.department_id;

 

#) 실행 계획 확인

select * from table(dbms_xplan.display_cursor(null, null, 'allstats last'));

→ 큰 값으로 빌드 테이블을 만들면 i/o 발생이 잦아서 성능이 안좋다. 그렇다고 값이 작게 나와도 좋지 않다.

(데이터 양이 적어서 값이 작게 나옴)

 


#3) 3개의 테이블로 join

select /*+ gather_plan_statistics leading(l,d,e) use_hash(d) use_hash(e) */ 
        d.department_id, d.department_name, e.employee_id, e.last_name, e.salary, l.city, l.street_address
from departments d, employees e, locations l
where d.department_id = e.department_id
and d.location_id = l.location_id;

 

#) 실행 계획 확인 

select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));

 


#) use_hash() 사용 

select  /*+ gather_plan_statistics leading(d,e,l) use_hash(e) use_hash(l) */ 
        d.department_id, d.department_name, e.employee_id, e.last_name, e.salary, l.city, l.street_address
from departments d, employees e, locations l
where d.department_id = e.department_id 
and d.location_id = l.location_id;

 

#) 실행 계획 확인

select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));

 

728x90
반응형
LIST

'Data Base > SQL 튜닝' 카테고리의 다른 글

Query Transformation, 서브쿼리 처리 방식(in, exists)  (0) 2024.02.23
pushing subquery, view merging, join 조건 pushdown  (0) 2024.02.23
Sort Merge Join  (0) 2024.02.20
join 실행 계획  (0) 2024.02.19
join 문, index 설정  (0) 2024.02.19