ORACLE JOIN
JOIN의 방식
- 조인연산(JOIN OPERATION)
- 여러 테이블에 저장된 데이터를 한번에 조회할 수 있게 하는 DBMS의 기능
- 두 집합(테이블) 간의 곱으로 데이터를 연결하는 가장 대표적인 데이터 연결 방법
- 물리적 조인 : 옵티마이저에 의해 발생하는 조인
- 논리적인 조인을 옵티마이저가 DBMS 내부에서 물리적인 조인으로 표현
- Join 작업을 할 때 옵티마이저는 어떤 방식으로 조인을 할지 실행계획을 세우게 됨
Nested-Loop Join
2개의 테이블의 행을 각각 모두 확인하여 조인하는 방법이다.
- 2개 이상의 테이블에서 하나의 집합을 기준으로 순차적으로 상대방 Row를 결합하여 원하는 결과를 조합하는 방식
- 선행 테이블의 처리 범위를 하나씩 액세스하면서 추출된 값으로 연결할 테이블을 조인
- 실행계획에서 먼저 실행되는 테이블이 Driving 테이블, 나중에 실행되는 것이 Driven 테이블
for (i=0; i<100; i++) {
for (j=0; j<100; j++) {
(생략)
}
}
Nested-Loop Join 절차:
- 선행 테이블에서 조건을 만족하는 첫 번째 행을 찾는다.
- 선행 테이블의 조인 키를 가지고 후행 테이블에 조인 키가 존재하는지 찾으러 가서 조인을 시도한다.
- 후행 테이블의 인덱스에 선행 테이블의 조인 키가 존재하는지 확인한다.
- 인덱스에서 추출한 레코드 식별자를 이용하여 후행 테이블을 액세스한다.
Nested-Loop Join 특징:
- 좁은 범위에 처리에 최적화 / 소량 데이터 조인 시 사용
- 한 레코드씩 순차적으로 처리
- Random Access 위주의 조인 방식 > 많은 양의 데이터 조인 시 Random Access 증가
- 후행 테이블(Driven)에는 조인을 위한 인덱스 생성 필요
- 실행속도 = 선행 테이블 사이즈 * 후행 테이블 접근횟수
Nested-Loop Join 주의사항:
- 데이터를 Random Access > 결과 집합이 많으면 느려짐
- 조인 컬럼에 index가 있어야 테이블 전체를 탐색하지 않고 필요한 행에 대해서만 탐색하여 효율적
- Row 수가 적은 테이블을 Driving 테이블로 선정해야 처리 속도 향상
- 테이블 중 적은 쪽을 Driven 테이블로 설정
Sort Merge Join
조인의 대상범위가 넓을 경우 발생하는 Random Access를 줄이기 위한 경우나 연결고리에 마땅한 index가 존재하지 않을 경우 해결하기 위한 조인 방안이다.
- 양쪽 테이블의 처리범위를 각자 Access하여 정렬한 결과를 차례로 Scan하면서 연결고리의 조건으로 Merge하는 방식
- 두 개의 테이블을 조인 칼럼으로 정렬하여 조인
Sort Merge Join 특징:
- 연결을 위해 Random Access를 하지 않고 스캔을 하면서 수행
- Nested Loop Join처럼 선행집합 개념이 없음
- 정렬을 위한 영역(Sort Area Size)에 따라 효율에 큰 차이 발생
- 조인 연산자가 '='이 아닌 경우 Nested Loop Join 보다 유리
- Outer 집합이 정렬되어 있는 경우, Non equi join을 사용하는 경우 유리
- 조인되는 컬럼에 index가 없는 경우 유리
Sort Merge Join 주의사항:
- 두 결과 집합의 크기가 차이가 많이 나는 경우에는 비효율적
- 정렬할 데이터가 많은 경우 부담이 가장 큰 방법
- Sorting 메모리에 위치하는 대상은 join key뿐만 아니라 Select list도 포함되므로 불필요한 Select 항목 제거
Hash Join
해싱 함수(Hashing Function)에 의한 탐색을 하여 조인을 수행하는 방식이다.
- 해싱 함수는 직접적인 연결을 담당하는 것이 아니라 연결될 대상을 특정 지역(partition)에 모아두는 역할만을 담당
- 해시값을 이용하여 테이블을 조인하는 방식
- Sort-Merge 조인은 정렬의 부하가 많이 발생하여, 이를 보완하기 위한 방법으로 Sort 대신 해쉬값을 이용하는 조인
Hash Join 특징:
- Random Access와 정렬에 대한 부담을 해소 > 대용량의 데이터 처리 시 사용됨
- parallel processing을 이용한 Hash Join은 대용량 데이터를 처리하기 위한 최적의 솔루션
- 2개의 조인 테이블 중 small rowset을 가지고 hash_area_size에 지정된 메모리 내에서 hash table 생성
- CBO에서만 가능하며, CPU 성능에 의존적(CPU 자원 많이 소비)
- Hash table 생성 후 Nested Loop처럼 순차적인 처리 형태로 수행
- 배치 작업에 유리
Hash Join 주의사항:
- 대용량 데이터 처리에서는 상당히 큰 hash area를 필요로 함으로, 메모리의 지나친 사용으로 오버헤드 발생 가능성
- 소량의 데이터를 조인할 때 오히려 불필요한 I/O가 증가할 수 있음
- 연결조건 연산자가 ‘=’인 동치조인인 경우에만 가능
- Equi Join에서만 가능 > Non-Equal 조인 조건인 경우, Hash Join으로 수행되지 못하고 Merge Join으로 수행됨
- Outer Table의 해시 키 칼럼에 중복값이 적은 경우에 사용
- 두 집합 중 크기가 작은 집합을 Outer Table로 결정
- 조인 칼럼에 적당한 index가 없는데 Nested Loop Join이 비효율 적일 때 사용
- Nested Loop Join에서 조인 칼럼 index가 있더라도 Random Access 부하가 심할 때 사용
참고, https://velog.io/@ynjch97/SQLD-JOINNested-Loop-Join-Sort-Merge-Join-Hash-Join