ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 상관 서브쿼리 (Correlated Subquery)란? 종류들
    데이터베이스 2024. 10. 22. 11:51
    728x90
    반응형

    메인 쿼리의 결과 개수만큼 서브 쿼리가 실행되는 경우는 **상관 서브쿼리(Correlated Subquery)**일 때 주로 발생합니다. 상관 서브쿼리는 메인 쿼리의 각 행에 대해 서브쿼리가 반복적으로 실행되는 구조를 가지므로, 메인 쿼리의 결과가 많아질수록 서브쿼리 실행 횟수도 그만큼 늘어납니다.

     

    1. 상관 서브쿼리 (Correlated Subquery)

    상관 서브쿼리는 메인 쿼리의 각 행에 의존해서 값을 계산하는 쿼리입니다. 예를 들어, 아래와 같은 쿼리가 있습니다:

     

    SELECT 
        a.id, 
        (SELECT COUNT(*) FROM orders o WHERE o.user_id = a.id) AS order_count
    FROM users a;

     

    이 경우 users 테이블의 각 행마다 orders 테이블에서 해당 user_id를 기준으로 한 COUNT를 계산하는 서브쿼리가 실행됩니다. users 테이블에 100개의 레코드가 있다면, 이 서브쿼리는 100번 실행됩니다.

    특징:

    • 서브쿼리가 메인 쿼리의 각 행에 의존해서 수행되므로, 메인 쿼리의 결과 개수만큼 반복 실행됩니다.
    • 이런 방식은 작은 데이터셋에서는 문제가 없을 수 있지만, 큰 데이터셋에서는 성능 저하를 일으킬 수 있습니다.

     

    EXISTS 

     

    EXISTS 안에 있는 서브쿼리상관 서브쿼리의 한 예로, 메인 쿼리의 각 행마다 서브쿼리가 조건에 맞는지를 평가하는 방식입니다. 그러나 EXISTS 서브쿼리는 실제로 서브쿼리가 일치하는 행을 찾는 즉시 종료하기 때문에, 다른 상관 서브쿼리들보다는 성능에 있어 효율적일 수 있습니다.

    1. EXISTS의 작동 방식

    EXISTS는 서브쿼리의 결과가 하나라도 존재하면 TRUE를 반환하고, 그렇지 않으면 FALSE를 반환합니다. 주로 특정 조건에 따라 행의 존재 여부를 검사할 때 사용됩니다.

    예를 들어, 다음과 같은 쿼리가 있다고 가정해봅시다:

     

    SELECT 
        a.id, a.name 
    FROM users a
    WHERE EXISTS (
        SELECT 1 
        FROM orders o 
        WHERE o.user_id = a.id
    );

     

    이 쿼리는 users 테이블의 각 행에 대해 서브쿼리를 실행하고, 해당 사용자가 orders 테이블에 주문 기록이 있는지를 검사합니다. EXISTS 서브쿼리 내에서 조건에 맞는 행이 발견되면 즉시 TRUE로 평가하고, 해당 사용자 정보를 반환합니다.

    2. EXISTS와 상관 서브쿼리의 관계

    EXISTS 서브쿼리의 특징은 메인 쿼리의 각 행에 의존하기 때문에 상관 서브쿼리로 간주된다는 점입니다. 서브쿼리의 조건에는 메인 쿼리의 컬럼이 사용되므로, 메인 쿼리의 각 행에 대해 서브쿼리가 조건에 맞는지 평가하게 됩니다.

    • 예를 들어, 위의 쿼리에서 o.user_id = a.id 조건은 메인 쿼리의 각 a.id 값에 의존하고 있습니다. 따라서 users 테이블의 각 행에 대해 orders 테이블에서 해당 사용자의 주문이 있는지를 확인하는 서브쿼리가 실행됩니다.
    • 하지만 중요한 점은 EXISTS 서브쿼리가 조건을 만족하는 첫 번째 행을 찾으면 즉시 평가를 중지한다는 것입니다. 즉, 조건을 만족하는 첫 번째 행을 찾은 시점에서 TRUE를 반환하고, 더 이상 서브쿼리를 실행하지 않습니다.

    3. EXISTS의 성능적 이점

    EXISTS는 다음과 같은 성능적 이점을 가지고 있습니다:

    • 서브쿼리가 조건을 만족하는 첫 번째 행을 찾으면 즉시 TRUE로 평가하고 종료하므로, 전체 결과 집합을 모두 확인하지 않아도 됩니다.
    • 일반적으로 EXISTS는 서브쿼리 내에서 SELECT * 대신 SELECT 1처럼 단순한 값을 반환하는 형태로 작성되는데, 이는 데이터베이스가 서브쿼리의 모든 행을 가져오는 것이 아니라 존재 여부만을 검사하기 때문입니다.
    • 특정 조건에 따라 존재 여부만을 확인할 때는 EXISTS가 JOIN보다 나은 성능을 제공할 수 있습니다.

    4. EXISTS vs. JOIN

    EXISTS와 JOIN은 서로 대체할 수 있는 경우가 있지만, 목적과 성능에서 차이가 있습니다:

    • EXISTS는 조건을 만족하는 행의 존재 여부만 검사하므로, 조건에 맞는 행을 찾자마자 처리를 멈출 수 있습니다.
    • 반면 JOIN은 조건에 맞는 모든 행을 가져와서 조합합니다. 따라서 JOIN은 결과를 기반으로 추가적인 데이터를 필요로 할 때 적합합니다.
    • 데이터가 많고 단순히 존재 여부만을 확인하고자 할 때는 EXISTS가 유리한 경우가 많습니다.

     

    5. 예시: EXISTS와 JOIN 비교

    EXISTS를 사용하는 경우:

    SELECT 
        a.id, a.name 
    FROM users a
    WHERE EXISTS (
        SELECT 1 FROM orders o WHERE o.user_id = a.id
    );

     

    • 이 쿼리는 users의 각 행에 대해 orders에서 해당 사용자(user_id)가 있는지 검사합니다.
    • 조건을 만족하는 첫 번째 주문이 발견되면 TRUE를 반환하고, 다음 사용자의 검사로 넘어갑니다.

    같은 로직을 JOIN으로 표현한 경우:

     

    SELECT DISTINCT 
        a.id, a.name 
    FROM users a
    JOIN orders o ON o.user_id = a.id;
    • 이 쿼리는 users와 orders를 조인하여 해당하는 모든 행을 가져옵니다.
    • 결과에는 중복이 발생할 수 있으므로 DISTINCT를 사용해야 동일한 결과를 얻을 수 있습니다.
    • 조건에 맞는 모든 조합을 가져오기 때문에, 많은 데이터를 다룰 때 성능이 낮아질 수 있습니다.

    결론적으로, EXISTS 안에 있는 서브쿼리는 상관 서브쿼리로 동작하며, 조건을 만족하는 첫 번째 행만 찾으면 그 즉시 평가를 중지하기 때문에, 성능 면에서 효율적일 수 있습니다.

    728x90
    반응형
Designed by Tistory.