DB

[MySQL] SELECT 문에서 EXISTS와 IN 조건절

인생아 2025. 6. 26. 15:44
반응형

MySQL SELECT 문을 다루면서 자주 마주치는 조건절이 있습니다. 바로 EXISTSIN 조건절입니다. 이 두 문법은 서브쿼리와 함께 많이 사용되며, 조건에 따라 행을 필터링하는 데 매우 강력한 도구입니다. 하지만 상황에 따라 성능과 결과가 달라질 수 있으므로, 그 차이를 명확히 이해하고 사용하는 것이 중요합니다.

 

✅ EXISTS란?

EXISTS서브쿼리의 결과가 존재하는지 여부를 평가합니다.
즉, 서브쿼리에서 하나라도 결과가 존재하면 TRUE, 결과가 없으면 FALSE를 반환합니다.

SELECT name
FROM employees e
WHERE EXISTS (
    SELECT 1
    FROM departments d
    WHERE d.manager_id = e.id
);

🔍 설명: 위 쿼리는 employees 테이블에서 departments의 manager_id로 등록된 직원만 조회합니다. EXISTS는 결과 유무만 판단하므로 SELECT 1처럼 아무 컬럼이나 써도 상관없습니다.

✅ IN이란?

IN 조건절은 지정한 목록(list)에 값이 존재하는지를 판단합니다. 서브쿼리와 결합하면 특정 컬럼 값이 서브쿼리 결과 안에 존재하는지 확인할 수 있습니다.

SELECT name
FROM employees
WHERE id IN (
    SELECT manager_id
    FROM departments
);

🔍 설명: 위 쿼리는 departments 테이블의 manager_id에 포함된 직원들을 조회합니다.

반응형

🧐 EXISTS vs IN 성능 차이

비교 항목 EXISTS IN
내부 동작 방식 서브쿼리 결과 존재 여부만 판단 서브쿼리 전체 결과를 메모리에 로딩함
NULL 처리 서브쿼리에 NULL이 있어도 문제없음 서브쿼리 결과에 NULL이 있으면 결과 영향
적합한 상황 큰 서브쿼리 결과에 적합 작은 리스트 필터링에 적합

💡 실전 팁:

  • 서브쿼리 결과가 크면 EXISTS를 사용하는 것이 효율적입니다.
  • 고정된 목록 필터링에는 IN이 더 간단하고 직관적입니다.

💡 실전 예제: 고객과 주문 테이블

아래는 customers와 orders 테이블이 있다고 가정하고, 다양한 쿼리 예제를 만들어봅니다.

1. EXISTS 예제 – 주문한 고객만 조회

SELECT c.name
FROM customers c
WHERE EXISTS (
    SELECT 1
    FROM orders o
    WHERE o.customer_id = c.id
);

2. IN 예제 – 주문한 고객만 조회

SELECT name
FROM customers
WHERE id IN (
    SELECT customer_id
    FROM orders
);

✔️ 두 쿼리는 동일한 결과를 출력하지만, 서브쿼리 결과가 매우 많다면 EXISTS가 더 효율적입니다.

반응형

⛔ IN 사용 시 주의사항: NULL

SELECT name
FROM customers
WHERE id IN (
    SELECT customer_id
    FROM orders
    UNION
    SELECT NULL
);

이 경우 id IN (...) 조건에 NULL이 포함되면, 예상치 못한 결과 누락이 발생할 수 있습니다.
NULL 값 필터링이 필요한 경우 EXISTS 사용을 고려하세요.

🔍 EXISTS를 활용한 NOT EXISTS 예제

SELECT name
FROM customers c
WHERE NOT EXISTS (
    SELECT 1
    FROM orders o
    WHERE o.customer_id = c.id
);

이 쿼리는 주문을 한 번도 하지 않은 고객을 조회합니다.
IN으로 표현하면 복잡해지지만, NOT EXISTS는 간결하게 조건을 걸 수 있는 장점이 있습니다.

💪 EXISTS와 IN 조건절 성능 최적화 팁

  • 서브쿼리 안에 인덱스를 사용하도록 유도하세요.
  • JOIN으로 변경 가능하다면 JOIN도 고려하세요.
  • MySQL 5.6 이상부터는 서브쿼리 최적화가 더 나아졌지만, 여전히 EXISTS가 더 빠른 경우가 많습니다.

📚 참고: 공식 가이드 문서

 

반응형