EXISTS

sykim·2025년 8월 29일

db

목록 보기
4/7

EXISTS서브쿼리(Subquery)에 결과 행이 존재하는지를 확인하는 역할을 합니다.

EXISTS의 핵심은 서브쿼리가 반환하는 실제 데이터 값이 아니라, 결과 집합의 존재 유무(True/False) 에만 관심이 있다는 점입니다.

EXISTS의 기본 동작 원리 🧐

EXISTSWHERE 절에서 사용되며, 다음과 같은 구조를 가집니다.

SELECT column1, column2, ...
FROM table1
WHERE EXISTS (
    SELECT 1
    FROM table2
    WHERE condition
);
  1. 메인 쿼리(Outer Query) 실행: 먼저 table1의 각 행을 순차적으로 읽습니다.
  2. 서브쿼리(Inner Query) 실행: table1의 현재 행 값을 이용하여 서브쿼리를 실행합니다. 이처럼 메인 쿼리의 값을 서브쿼리가 참조하는 것을 연관 서브쿼리(Correlated Subquery) 라고 하며, EXISTS는 대부분 이런 형태로 사용됩니다.
  3. 존재 여부 판단:
    • 서브쿼리가 하나 이상의 행을 반환하면, EXISTS 조건은 TRUE가 되어 메인 쿼리의 해당 행이 결과에 포함됩니다.
    • 서브쿼리가 어떠한 행도 반환하지 않으면(결과 집합이 비어있으면), EXISTS 조건은 FALSE가 되어 메인 쿼리의 해당 행은 결과에서 제외됩니다.

가장 중요한 특징은 "Short-circuit" 평가를 한다는 것입니다. 서브쿼리에서 조건을 만족하는 첫 번째 행을 찾는 즉시 평가를 중단하고 TRUE를 반환하므로, 불필요한 전체 테이블 스캔을 피할 수 있어 성능상 큰 이점을 가집니다.


## EXISTS vs. IN vs. JOIN

EXISTS는 종종 IN이나 JOIN으로 대체할 수 있지만, 내부 동작 방식과 성능에서 중요한 차이가 있습니다.

EXISTS vs. IN

구분EXISTSIN
동작 방식메인 쿼리의 각 행에 대해 서브쿼리를 실행하여 조건 만족 여부 확인서브쿼리를 먼저 실행하여 결과 리스트를 메모리에 저장 후, 메인 쿼리의 값과 비교
성능서브쿼리의 결과 집합이 매우 클 때 유리 (첫 행만 찾으면 멈추므로)서브쿼리의 결과 집합이 작을 때 유리
서브쿼리SELECT 1, SELECT * 등 컬럼은 중요하지 않음 (존재 여부만 판단)SELECT column 처럼 비교할 특정 컬럼을 명시해야 함
NULL 처리NOT EXISTSNULL 값에 영향을 받지 않아 직관적NOT IN은 서브쿼리 결과에 NULL이 포함되면 예기치 않은 결과(0개 행)를 반환할 수 있음

예시: 주문(Orders)이 하나라도 있는 고객(Customers)을 찾는 경우

SQL

-- EXISTS 사용 (효율적)
SELECT c.customer_name
FROM Customers c
WHERE EXISTS (
    SELECT 1
    FROM Orders o
    WHERE o.customer_id = c.customer_id -- 연관 서브쿼리
);

-- IN 사용
SELECT c.customer_name
FROM Customers c
WHERE c.customer_id IN (
    SELECT o.customer_id
    FROM Orders o
);

Orders 테이블이 매우 크다면 EXISTS가 훨씬 효율적입니다.


EXISTS vs. JOIN

JOIN은 두 테이블을 연결하여 양쪽 테이블의 컬럼을 모두 결과로 가져올 때 사용합니다. 반면 EXISTS는 한 테이블의 데이터를 필터링하기 위해 다른 테이블의 존재 여부만 확인할 때 사용합니다.

JOIN은 1:N 관계에서 N쪽 테이블과 조인하면 1쪽 테이블의 행이 중복될 수 있지만, EXISTS는 중복을 발생시키지 않습니다. 이런 특성 때문에 EXISTS세미 조인(Semi Join) 역할을 수행한다고 말합니다.

예시: 주문이 있는 고객 정보 "만" 필요한 경우

SQL

-- JOIN 사용 (중복 발생 가능)
SELECT DISTINCT c.customer_id, c.customer_name -- 중복 제거를 위해 DISTINCT 필요
FROM Customers c
JOIN Orders o 
ON c.customer_id = o.customer_id;

-- EXISTS 사용 (중복 없음, 더 효율적)
SELECT c.customer_id, c.customer_name
FROM Customers c
WHERE EXISTS (
    SELECT 1
    FROM Orders o
    WHERE o.customer_id = c.customer_id
);

이 경우, 고객 정보만 필요하므로 JOIN보다 EXISTS가 더 명확하고 성능도 좋습니다.


## NOT EXISTS의 활용

NOT EXISTS는 서브쿼리의 결과가 존재하지 않을 때 TRUE를 반환합니다. 특정 조건을 만족하는 데이터가 없는 행을 찾을 때 매우 유용하며, 안티 세미 조인(Anti Semi Join) 역할을 합니다.

예시: 한 번도 주문한 적이 없는 고객(Customers)을 찾는 경우

SQL

SELECT c.customer_name
FROM Customers c
WHERE NOT EXISTS (
    SELECT 1
    FROM Orders o
    WHERE o.customer_id = c.customer_id
);

이 쿼리는 LEFT JOINIS NULL을 사용하는 것보다 더 직관적이고 성능이 좋은 경우가 많습니다.

## 결론 🎯

정리하자면, EXISTS 절은 다음과 같은 상황에서 강력한 성능과 명확한 가독성을 제공합니다.

  • 대용량 테이블의 데이터 존재 여부를 확인할 때
  • 다른 테이블의 데이터를 가져올 필요 없이, 필터링 조건으로만 사용하고 싶을 때
  • JOIN 사용 시 발생하는 결과 행의 중복을 피하고 싶을 때 (Semi Join)
  • 특정 데이터가 없는 경우를 검색하고 싶을 때 (NOT EXISTS -> Anti Semi Join)
profile
공부 정리 블로그

0개의 댓글