조인 Summary

Inyeob Kim·2023년 3월 22일

수행 방식에 따른 조인의 종류

조인을 어떤 방식으로 수행하는가에 따라 조인은 NL Join, Sort Merge Join, Hash Join으로 분류한다.

수행 방식에 따른 조인의 종류는 SQL의 성능과 밀접한 관련이 있다.

1. NL Join

Nested Loop Join은 많은 사용자가 접속하여 사용하는 OLTP(Online Transaction Processing) 시스템에서 가장 보편적으로 사용되는 조인 방식으로, 조인해야할 데이터가 많지 않은 경우에 유용하다.

적절한 드라이빙 테이블 선정 -> WHERE절에 정의된 검색 조건을 만족하는 데이터 추출 -> 해당 데이터를 가지고 조인 대상 테이블 (INNER TABLE) 을 반복적으로 검색 -> 조인 조건을 만족하는 최종 결과값 얻어냄

주의 사항

  • NL Join 방식을 채택할 시 드라이빙 테이블의 선택이 매우 중요함!!! (WHERE절에 명시된 조건을 만족하는 결과가 적은 쪽을 택하는것이 유리)
  • INNER TABLE의 조인 조건으로 사용도리 컬럼에 인덱스가 존재하는지 여부도 성능을 좌우함 (매번 FULL TABLE SCAN할 우려 있음)

예시

SELECT E.emp_no,
	   J.job_title,
       E.salary,
       D.dept_name
FROM   emp E,
	   jobs J,
       dept D
WHERE  E.emp_no < 103
       AND E.job_id = J.job_id
       AND E.dept_no = D.dept_no;

단계적으로 생각해보자!

단계 1 : SELECT ... FROM emp E WHERE E.emp_no < 103
단계 2 : SELECT ... FROM jobs J WHERE 단계 1을 만족하는 E.job_id = J.job_id
단계 3 : SELECT ... FROM dept D WHERE 단계 2를 만족하는 E.dept_no = D.dept_no

각 단계에 대해 점검해야할 기본적인 튜닝 요소들은 아래와 같음.

단계 1 : 조건절에 제시된 emp_no 컬럼에 인덱스가 존재하는가?
단계 2 : jobs 테이블에 대한 조인 조건인 job_id 컬럼에 인덱스가 존재하는가?
단계 3 : dept 테이블에 대한 조인 조건인 dept_no 컬럼에 인덱스가 존재하는가?

또한 단계2를 수행하기 위한 단계1의 결과 건수가 얼마나 되는가를 점검해야함. 만약 단계1에서 추출해낸 결과 건수가 단계2에서 조인할 jobs테이블의 건수보다 많다면 NL Join 방식이 성능 검색에 유리하지 않을 수 있음. 마찬가지로 단계3을 수행하기 위한 단계2 까지의 결과 건수도 같은 이유로 점검해볼 필요 있음.

다시한번 강조하지만!!

NL Join은 다른 조인 방식에 비해 드라이빙 테이블의 대상 데이터를 처리하는 성능이 매우 매우 중요함!! 수행 방식의 특성상 순차적으로 조인을 수행하기 때문에 드라이빙 테이블의 데이터 처리속도가 느려지면 이후 수행 속도도 자연스럽게 지연됨.

NL Join 방식을 사용하는 SQL튜닝 할 때는 드라이빙 테이블을 잘 선정하였는가, 조인 순서가 효율적인가 (드라이빙 테이블에서 추출되는 건수가 많다면 LEADING과 같은 힌트를 써서 테이블 조인 순서를 바꿔보면서 테스트해보는 것도 방법), 드라이빙 테이블의 인덱스가 적절한가, INNER TABLE의 조인 컬럼에 인덱스가 있는가를 판단하여 차근차근 해법을 찾는 것이 중요함...!

2. HASH JOIN

Nested Loop Join 은 드라이빙 테이블에서 접근할 데이터가 적고, 조인될 테이블에서 접근해야할 데이터 또한 적을 경우 최적의 성능을 보여준다고 했다. 이와 반대로, 많은 양의 데이터를 조인해야 하는 경우에 옵티마이저는 NL Join 보다는 Sort Merge Join 이나 Hash Join 방식을 선택한다.

해쉬 조인은 조인될 두 테이블 중 하나를 해시 테이블로 선정하여 조인될 테이블의 조인 키 값을 해시 알고리즘으로 비교하여 매치되는 결과값을 얻는 방식을 말함.

해쉬 조인은 비용 기반 옵티마이저를 사용할 때에만 채택할 수 있는 조인 방식이며, '=' 비교를 통한 조인에서만 사용할 수 있다.

해쉬 조인으로 처리되고 있는 SQL을 튜닝할 때는 조인 컬럼보다 변수 및 상수와 비교하고 있는 컬럼의 인덱스 유무에 중점을 두고 확인해야함.

3. Sort Merge Join

이 방식은 앞서 본 NL Join처럼 테이블들의 조인 순서가 중요하지 않다.

조인하고자 하는 두 테이블의 행들을 조인 조건 컬럼을 기준으로 정렬한 후, 서로 Merge하여 매치되는 결과를 출력한다. 따라서 조인 조건 컬림이 정렬되어 있다면 검색 속도 향상에 도움이 된다.

Sort Merge Join은 대량의 데이터를 조인하는데 유리하고 조인 조건으로 <, <=, >, >= 와 같은 범위 검색용 연산자가 사용된 경우에 유용하게 사용되며, 앞서 말한 것처럼 조인의 순서가 중요하지 않으므로 드라이빙 테이블이라는 개념이 무의미함.

조인 컬럼이 정렬되어 있지 않거나 '='로 비교하는 조인인 경우에는 해쉬 조인 방식으로 변경할 것을 권고함.

4. 서브쿼리

하나의 SQL 내에 존재하는 또 다른 SELECT문을 의미하며, 이와 같은 서브쿼리를 포함하고 있는 SQL을 메인쿼리라고 한다.

스칼라 서브쿼리

  • SELECT절에서 사용되는 서브쿼리는 보통 스칼라 서브쿼리이다. 스칼라 서브쿼리란, 한 컬럼으로 이루어진 한 행의 결과를 리턴하는 서브쿼리를 말하는데, SELECT절에서 사용하는 서브쿼리의 결과 건수가 2건 이상일 경우 SQL오류가 발생한다.
  • SELECT절의 서브쿼리는 메인쿼리의 결과 건수만큼 반복해서 실행되어야 하기 때문에 1회 수행 시 드는 비용이 높으면, SQL의 전체 성능에 좋지 않은 영향을 끼칠 수 있다.
  • 스칼라 서브쿼리는 재활용이 가능하다. (함수 대신 스칼라 서브쿼리를 사용하면 결과값을 재활용하여 호출 횟수를 줄일 수 있음)
profile
코어뱅킹 주니어 개발자

0개의 댓글