본문 바로가기
DB

[DB/SQL] 중첩 질의 보다 JOIN Query가 더 효율적인 이유

by persi0815 2024. 10. 27.

데이터베이스를 설계하고 SQL 쿼리를 작성할 때, 동일한 결과를 얻기 위해 중첩 질의(Subquery)와 JOIN 쿼리를 사용하는 두 가지 방법을 고민하는 경우가 있다. 이 두 방식 중 대량의 데이터셋이나 여러 테이블 간의 연결이 많은 경우에 JOIN 쿼리가 더 효율적으로 작동하는 이유를 살펴보자. 

 

1. 중첩 질의(Subquery)란?

중첩 질의는 SQL 쿼리 안에 또 다른 쿼리가 중첩된 형태로, 주로 결과 값을 필터링하거나 계산하는 데 사용된다. 

SELECT name
FROM employees
WHERE department_id = (
    SELECT id
    FROM departments
    WHERE name = 'HR'
);

 

위 쿼리는 ‘HR’ 부서의 ID를 먼저 찾은 뒤, 해당 ID에 속한 직원들의 이름을 조회한다. 중첩 질의는 직관적으로 이해하기 쉬울 수 있지만, employees 테이블의 각 행에 대해 departments 테이블을 다시 검색해야 하기에 성능적인 문제가 있을 수 있다. 

 

2. JOIN 쿼리란?

JOIN은 두 개 이상의 테이블을 결합하여 원하는 데이터를 하나의 결과 집합으로 반환하는 방식이다. 위 중첩 질의와 동일한 결과를 JOIN으로 표현하면 아래와 같다.

SELECT e.name
FROM employees e
JOIN departments d ON e.department_id = d.id
WHERE d.name = 'HR';

 

이 쿼리는 employees와 departments 테이블을 한 번의 작업으로 결합한 후, ‘HR’ 부서의 이름에 해당하는 데이터를 필터링한다.  대개 테이블 간의 관계를 활용하기에 인덱스가 적절하게 설정되어 있다면 효율적이다. 

 

3. 대량의 데이터셋을 다룰 때에는 JOIN이 중첩 질의보다 효율적이다

3.1 데이터베이스 옵티마이저의 역할과 JOIN의 처리 방식

데이터베이스 관리 시스템(DBMS)의 쿼리 옵티마이저는 실행 계획(Execution Plan)을 생성할 때, 가능한 효율적인 방식을 선택한다. JOIN 쿼리는 옵티마이저가 제공하는 다양한 최적화 기술을 활용할 수 있어 중첩 질의보다 효율적일 가능성이 높다. 

 

1. 인덱스 활용

  • JOIN은 테이블 간의 연결 시 인덱스를 적극적으로 활용할 수 있습니다. 옵티마이저는 사용 가능한 인덱스를 탐색하고, 이를 통해 데이터 액세스 범위를 최소화한다.
  1.  

2. 해시 및 병렬 처리

  • JOIN 연산은 해시 테이블(Hash Table)을 생성하거나 병렬 처리(Parallel Processing)를 통해 대량의 데이터를 빠르게 처리할 수 있다. 반면, 중첩 질의는 이러한 최적화가 제한적이다.

3. JOIN 최적화 기술

  • Merge Join: 정렬된 두 테이블을 병합하여 데이터를 결합.
  • Nested Loop Join: 소규모 테이블을 기준으로 반복적으로 결합.
  • Hash Join: 해시 테이블을 생성하여 대량의 데이터를 빠르게 처리.

이러한 방식들은 모두 중첩 질의가 사용하는 단순 반복보다 훨씬 효율적이다. 

 

3.2 중첩 질의의 비효율성

중첩 질의는 본질적으로 “루프 안의 루프”와 유사한 방식으로 동작한다. 즉, 외부 쿼리가 실행될 때마다 내부 쿼리가 반복적으로 실행될 가능성이 높다. 

SELECT name
FROM employees
WHERE department_id IN (
    SELECT id
    FROM departments
    WHERE location = 'New York'
);

 

위 쿼리는 각 department_id에 대해 내부 쿼리가 실행되어 결과적으로, 데이터셋이 클수록 성능이 저하된다는 문제점이 있다. 

 

https://hangbok-archive.com/data/rdbms/%EC%84%9C%EB%B8%8C%EC%BF%BC%EB%A6%AC-vs-join/

 

4. 중첩 질의를 사용해야 하는 경우

JOIN이 대부분의 상황에서 더 효율적이지만, 중첩 질의가 유용한 경우도 있다. 

 

코드의 가독성이 좋고, 복잡한 조건을 적용하기 용이하기에

1. 집계 함수(Aggregate Function)와 결합하여 사용할 때 표현이 간결해지는 경우가 있다. 

2. 내부 쿼리에서 조건을 설정하여 데이터를 필터링하는게 더 편할 경우가 있다.

 

즉, 작은 데이터 셋이나 적은 수의 행에 대한 필터링은 효과적일 수 있다. 

 

5. Join이 중첩 질의를 대체할 수 없는 경우

대부분의 상황에서 웬만하면 Join이 Subquery를 대체할 수 있다고 배웠는데, 대체할 수 없는 경우가 있다고 한다. 

 

1. Group by를 사용하여 집계 값을 계산하는 서브 쿼리가 From절에 들어가는 경우

2. 서브 쿼리의 결과 집계 값이 Where 절에 들어간느 경우

 

결론

데이터베이스 옵티마이저가 JOIN의 인덱스 활용, 해시 테이블 생성, 병렬 처리 등 다양한 최적화 기법을 적용한다는 매우 큰 장점이 있어 실무에서는 중첩 질의 대신 JOIN을 우선적으로 고려하는 것이 권장되지만, 
쿼리의 가독성과 요구 사항에 따라 중첩 질의가 더 적합할 수도 있으므로, 실행 계획을 분석하여 적절한 방식을 선택하는 것이 중요하다!!

 

 

참고

https://hangbok-archive.com/data/rdbms/%EC%84%9C%EB%B8%8C%EC%BF%BC%EB%A6%AC-vs-join/

 

SQL 성능 비교 : 서브쿼리 vs JOIN - H-A

서브쿼리 vs JOIN : 서브쿼리와 JOIN 문은 데이터베이스에서 정보를 추출하는 두 가지 주요 방법입니다. 성능 차이는 데이터 양, 인덱스의 존재 여부, 데이터베이스 종류 등에 따라 다를 수 있습니

3.35.198.107