본문 바로가기
IT/Oracle

오라클 조인 방식 종류와 이해.

by heavenLake 2022. 7. 22.
반응형

원본사이트:https://dataonair.or.kr/db-tech-reference/d-lounge/expert-column/?pageid=3&mod=document&keyword=%ED%94%8C%EB%9E%9C%EC%9D%84+%EB%B3%B4%EB%8A%94+%EB%B2%95&uid=52359

 

조인이란 무엇인가

흔히 조인이라 하면 Inner Join 혹은 Outer Join을 생각하는 경우가 많다. 이번 연재 내용은 그러한 조인이 아니라 테이블 간에 어떤 방식으로 접근하는가에 대한 조인이다. 다시 말해서 오라클에서 조인 방식이란, 테이블 간의 데이터 접근 방법을 의미한다.


관계형 데이터베이스에서 쿼리는 Join 없이 단독으로 사용하는 경우가 거의 없다. 대부분의 쿼리는 여러 테이블 간에 관계를 맺는 경우이다. 이러한 테이블 간 관계에 있어서 어떠한 방법으로 접근하는가에 대한 내용이 바로 조인 방식에 대한 내용이다. 오라클에서 조인은 아주 중요한 의미를 가진다. 왜냐하면 어떠한 조인 방식을 선택하느냐에 따라서 쿼리의 비용과 성능이 달라지기 때문이다.

 

조인 방식은 아래와 같이 크게 3가지 경우로 나뉜다.


1. Nested Loop Join: 순차적 루프에 의한 접근 방식

2. Sort Merge Join: 정렬을 통한 접근 방식

3. Hash Join: 해시 함수를 이용한 접근 방식


도시 사이를 이동할 때, 선택할 수 있는 교통 수단은 택시, 버스, 기차, 자전거, 도보 등이 있다. 어떤 교통 수단이 좋고, 어떤 교통 수단이 나쁘다고 논하는 것은 의미가 없다. 단지 그때그때 상황에 맞게 적절한 수단을 선택하면 되기 때문이다. 소수의 인원이 빨리 가기를 원한다면 택시를 타면 될 것이고, 많은 사람이 이동해야 한다면 버스를 선택하면 된다. 가까운 거리에 있는 도시라면 자전거를 이용할 수도 있고, 더 가까운 거리라면 걸어가는 것도 좋은 방법이다. 도보로 갈 수 있는 거리를 버스 타고 이동한다면 아까운 비용만 지불한 꼴이 될 것이다. 택시를 타고 빨리 가야 할 거리를 걸어서 간다면 비용은 아꼈을지 몰라도 그만큼 시간을 쓴 것이다.


마찬가지로 오라클에서도 조인 방식에 따른 호불호는 없다. 단지 상황에 따른 선택만 있을 뿐이다. Nested Loop Join은 택시와 비슷하다. 소량의 데이터 처리에 적합한 조인 방식이다. Hash Join 방식은 버스와 비슷하다. 대량의 데이터 처리에 효율적인 조인 방식이다. Sort Merge Join 방식은 요즘 거의 사용하지 않으므로 논외로 하겠다. 3가지 조인 방식에 대해 좀 더 구체적으로 살펴 보자.

 

오라클 조인 방식 - Nested Loop Join

Nested Loop Join(NL 조인)은 여러분이 가장 흔하게 접할 수 있는 오라클 조인 방식일 것이다. OLTP(Online Transaction Processing) 쿼리에서 가장 일반적이고 흔한 조인 방식이다. 소량의 데이터를 처리하거나 부분범위 처리에 적합하다. NL 조인의 방식은 아래의 For 문으로 이해하면 쉽다.

 



개발자라면 For ~ Loop 문의 수행 방법을 알 것이다. NL 조인은 이러한 For ~ Loop 문의 수행 방법과 동일한 것으로, 테이블 간 조인을 순차적으로 수행한다. 테이블 간 접근 순서가 매우 중요하고, 선행 테이블의 처리 범위가 작아야 하고, 조인절의 목적지 컬럼에 반드시 인덱스가 존재해야 한다.

 

Nested Loop Join 처리 순서는 다음과 같다.


1. 고객 테이블에서 이름이 ‘홍길동’인 고객을 구한다. (선행 테이블 결정)

2. ‘홍길동’ 고객의 수만큼 순차적으로 주문 테이블을 고객번호 컬럼으로 접근한다. (순차적 접근)

3. 주문 테이블에서 주문일자가 ‘20141201’인 정보만 필터한다.

 

오라클 조인 방식 - Sort Merge Join

오라클 조인 방식 Sort Merge Join은 성능이 더 좋은 Hash Join으로 대체할 수 있기 때문에 여러분이 접할 가능성은 거의 없다. 이 조인 방식은 조인절에 인덱스가 없을 때 자주 발생한다. Sort가 발생하므로 대상 건수가 많을수록 Sort 부하가 커진다. 따라서 성능이 저하될 수 있다. 초등학교 다닐 때 선생님이 짝꿍을 정해 주는 방법과 같은 방법이라 할 수 있다.

 





Sort Merge Join 처리 순서는 다음과 같다.


1. 고객 테이블에서 이름이 ‘홍길동’인 고객을 구한 후 고객번호 순으로 정렬한다. (SORT)

2. 주문 테이블에서 주문일자가 ‘20141201’인 주문을 구한 후 고객번호 순으로 정렬한다. (SORT)

3. 정렬된 고객 정보와 정렬된 주문 정보를 고객번호로 조인한다. (MERGE)



오라클 조인 방식 - Hash Join

오라클 조인 방식 Hash Join은 대량의 데이터 처리에 유리하다. NL 조인의 처리 범위가 부담스럽거나, Sort Merge Join의 Sort가 부담스러울 때 사용하면 좋다.

메모리에 해시 테이블을 생성하고, 해시 함수를 이용해 연산 조인을 함에 따른 CPU 사용이 증가할 수 있으므로 조회 빈도가 높은 온라인 프로그램에는 적합하지 않는 조인 방식이다.

 



위 그림은 1,000쌍의 부부가 흩어져 있는 체육관에서 각자 배우자를 찾는 방법을 Hash Join 방식으로 설명한 것이다. 아무런 규칙 없이 모든 사람이 배우자를 찾고자 동시에 움직인다면 많은 시간이 소요될 것이다. 하지만 위의 그림과 같은 Hash Join 방식은 그러한 시간을 줄일 수 있다. 먼저 남자들이 본인 성씨 구역으로 집결하면, 여자들이 남편의 성씨 구역으로 가서 남편을 찾는다. 여기서 성씨 구역들은 해시 테이블을 의미하며, 성씨 분류는 해시 함수를 의미한다.

김씨를 남편으로 둔 여자들은 다른 여자들보다 찾는 시간이 더 많이 걸릴 것이다. 마찬가지로 Hash Join에서도 하나의 버킷(구역)에 많은 해시키(김씨들)가 존재할 때, 그만큼 액세스를 많이 해야 하므로 처리 시간이 늘어나서 성능이 떨어지게 된다.



Hash Join 처리 순서는 다음과 같다.


1. 조직 테이블에서 사업부가 ‘강원사업부’인 조직들을 구한 후, 조인절 컬럼인 조직코드를 해시 함수로 분류한 다음, 해시 테이블을 생성한다.

(해시 함수를 이용해 해시 테이블 생성)

2. 집계 테이블에서 처리년월이 ‘201412’인 자료를 구한 후, 조인절 컬럼인 조직코드를 해시 함수로 변환 후 해시 테이블로 순차적으로 접근한다.

(해시 함수를 통해 해시 테이블 탐색)


Hash Join에서는 작은 테이블을 먼저 접근하는 것이 성능 면에서 더 좋다. 해시 테이블 구성 작업에 부하가 많이 발생하기 때문이다. 작은 테이블에 접근해 Hash 함수로 해시 테이블을 생성하고, 이후 큰 테이블에 접근해 Hash 함수를 통해 순차적으로 해시 테이블로 접근한다. 이러한 조인 방식은 대량 데이터를 처리하는 배치성 프로그램에 유용하게 사용된다.

 

오라클 조인 방식의 특징 비교

지금까지 오라클의 3가지 조인 방식인 Nested Loop Join, Sort Merge Join, Hash Join에 대해 알아보았다. 아래 표는 위의 3가지 조인의 장단점과 특징을 요약한 것이다.

 



조인 방식과 조인 순서 결정하기

주어진 작업의 성격과 DB 환경에 따라 조인 방식을 결정해야 하며, 조인 방식을 결정했다면 성능에 영향을 미치는 조인 순서도 결정해야 한다. 이러한 일은 주어진 정보를 바탕으로 직관적이고 종합적으로 판단해, 능동적으로 수행해야 한다. 오라클 옵티마이저가 우리에게 제공하는 정보만을 맹신해서는 안되며, 단지 참고 정보로만 활용해야 한다. 조인절에 참여하는 테이블 수가 많으면 많을수록 점점 더 복잡하고 결정하기 곤란하지만, 우리 스스로 최선의 조인 방식을 결정하고 조인 순서를 정하는 노력을 게을리 해서는 안된다. 이번 연재 내용에 더해 다음과 같은 지난 연재 내용을 다시 한번 읽어보면 쉽게 이해할 수 있을 것이다.

 

07회: 누구도 알려주지 않았던 '오라클 인덱스 생성도'의 비밀

08회: 누구도 알려주지 않았던 '오라클 쿼리 작성의 비법‘

09회: 쿼리 최적화 및 튜닝을 위한 오라클 공정쿼리 작성법



다음 연재에서는 오라클 힌트절에 대해 자세히 알아 보겠다.

 

용기를 갖자
오라클 DB뿐 아니라 대부분의 DB 구성 알고리즘은 어느 날 ‘하늘에서 뚝 떨어져 새로 만들어진 것’이
아니라 실생활에서 이용되는 혹은 이미 상식 수준에서 인지되는 그런 보편적인 원리를 바탕으로
만들어졌으므로 쉽게 접근하고 이해할 수 있다. 서두에서 말했듯이 ‘레몬시장이론’을 상기하며
DB를 지레짐작으로 어려워하지 말고 용기를 내고 하나씩 터득해 나가기를 바란다.
이 글은 DB 전문가 수준의 이해를 요구하지는 않는다. 단지 DB에 대해서 더 친숙하고 더 쉽게
이해하고 접근하길 바랄 뿐이다. 이 글을 읽으면서 궁금하거나 의문 나는 점이 있으면,
댓글을 달아주실 것을 적극 바란다. 아무리 어렵고 힘든 일이더라고 ‘관계’와 ‘소통’으로
풀어나갈 수 있음을 다시 한 번 믿으며….



[지난 문제의 정답과 풀이]

원리를 이해하고 논리로 풀어가는, 쉬어가는 DB 문제



지난 연재에 출제한 ‘원리를 이해하고 논리로 풀어가는, 쉬어가는 DB 문제’에 대한 정답과 해설은
아래와 같다. 문제를 풀면서 DB 원리를 하나씩 배우고 이해할 수 있다.

 







[이번 호 문제]

원리를 이해하고 논리로 풀어가는, 쉬어가는 DB 문제



각 연재의 말미에 간단하면서도 재미있고 생각해 보는 문제를 출제하려 한다. 모든 문제는 DB의 원리를 이해할 수 있는 문제로 출제할 예정이다. 문제를 풀면서 DB 원리를 하나씩 배우고 이해할 수 있다. 정답과 그에 대한 설명은 다음 연재에서 한다.

 




반응형

댓글