[Oracle] Join의 종류(Nested Join, Sort-Merge Join, Hash Join)

HYEOB KIM·2023년 6월 12일
0

Oracle

목록 보기
41/58

1. Nested Join


(예시 쿼리)

select e.ename, d.dname
from emp e, dept d
where e.deptno = d.deptno

위와 같은 쿼리가 있습니다. 쿼리의 결과는 어떻게 출력될까요?

사원 테이블과 부서 테이블에서 부서 번호가 같은 행의 사원이름과 부서이름을 모두 출력할 것입니다.

그런데 join 방식에 따라 where절의 조건에 맞는 행을 조회하는 방식에 차이가 있습니다.

Nested Join의 방식은 흔히 이중 for문과 같다고 합니다.
코드로 예를 들자면 아래와 같은 방식이죠.

for i in range(n): # outer loop
  for j in range(m): # inner loop

여기서
outer loop에 해당하는 테이블이 driving(선행) 테이블이라 하며
inner loop에 해당하는 테이블은 driven(후행) 테이블이라 합니다.

driving 테이블이 emp, driven 테이블이 dept일 때
좀 더 자세하게 Nested Join의 방식은 아래와 같습니다.

1) 사원 테이블(emp), 부서 테이블(dept)을 메모리에 복사합니다
2) 사원 테이블(emp - driving 테이블)에서 사원이름(e.ename) 꺼내서 임시 작업 공간(PGA)으로 가져갑니다(인덱스 상황이나 다른 요소에 따라 순서가 변경될 수도 있음)
3) 부서 테이블(dept - driven 테이블)에서 해당 부서명(d.dname)을 찾으러 가는데 그때 위 SQL의 where조건을 보고 해당 조건에 맞는 데이터를 찾아서 부서명(d.dname)을 가져옵니다
4) 한 행의 작업이 끝나면 다시 처음 테이블(emp - driving 테이블)로 돌아가서 두번째 행의 이름을 임시 작업 공간으로 가져옵니다
5) 다시 부서 테이블(dept - driven 테이블)에 가서 두번째 부서번호(deptno)와 동일한 부서번호를 가진 부서명(d.dname)을 꺼내옵니다

즉, driving 테이블의 첫번째 행을 조회한 후 driven 테이블의 행을 전체 조회하여 where 절의 조건에 맞는 행이 있는지 보고, driving 테이블의 두번째 행을 조회한 후 driven 테이블의 행을 전체 조회하여 where 절의 조건에 맞는 행이 있는지 보고...
이 과정을 driving 테이블의 행을 모두 조회할 때까지 수행됩니다.

이때, driving 테이블의 행의 수만큼 Join이 수행됩니다.
그래서 driving 테이블의 행의 수가 적을 수록 성능에 유리합니다.
어떤 테이블을 driving 테이블로 할지는 옵티마이저(Optimizer)가 결정합니다.
이렇듯 모든 행을 조회하기 때문에 Join 컬럼에 대한 인덱스를 생성해주면 마찬가지로 성능에 유리합니다.

2. Sort-Merge Join


(예시 쿼리)

select e.ename, d.dname
from emp e, dept d
where e.deptno = d.deptno

Nested Join에서는 모든 행을 조회하기 때문에 Join 컬럼에 대한 인덱스를 생성해주면 성능에 유리하다고 했습니다.

그런데 Sort-Merge Join 방식은 인덱스가 없을 경우에도 빨리 해당 데이터를 찾아서 결과를 출력할 수 있도록 하는 Join 방식입니다.

Sort라는 단어에서도 유추할 수 있듯이, where 절의 조건(deptno)를 기준으로 정렬을 수행합니다. 그리고 서로 같은 값을 비교해서 찾아냅니다.

문제는 정렬을 수행하는데 시간이 너무 오래걸린다는 점입니다. 그래서 이를 보완하는 방식은 Hash Join 방식을 많이 이용하게 됩니다.

3. Hash Join


Hash Join 방식은 일반적으로 양쪽 테이블 모두 Join 컬럼에 인덱스가 없을 경우에 사용합니다.

자세한 진행 방식은 아래와 같습니다.

1) 두 테이블 중에서 범위가 좁은 테이블(driving 테이블이 됨)을 메모리로 가져옵니다.
2) driving 테이블의 Join 조건 컬럼의 데이터를 Hash 함수에 넣어서 나온 Hash Value 값으로 Hash Table을 생성합니다.
3) driven 테이블의 Join 조건을 Hash 함수에 넣어서 Hash Value를 생성하고 이 값을 driving 테이블의 Hash Table의 값과 비교하여 같은 값을 찾아 매칭합니다.

이러한 Hash Join 방식은 Sort-Merge Join 방식에 비해 약 2배 이상의 성능 차이를 보입니다.


참고

profile
Devops Engineer

0개의 댓글