티스토리 뷰

300x250

SQL을 공부하다 보면 EXISTSIN 은 거의 반드시 만나게 됩니다.

둘 다 비슷해 보이지만, 실무에서는 성능 차이 때문에 신경 써야 하는 경우가 꽤 많습니다. 특히 데이터 양이 많아지면 “둘 중 아무거나 써도 되겠지”가 아니라, 어떤 상황에서 무엇을 쓰는 게 더 적절한지 판단하는 게 중요해집니다.

먼저 핵심부터
IN 은 보통 값 목록과 비교하는 느낌으로 이해하면 쉽고,
EXISTS조건을 만족하는 행이 존재하는지만 확인한다고 보면 됩니다.
실무에서는 서브쿼리 결과가 크거나, 존재 여부만 중요할 때는 EXISTS가 유리한 경우가 많습니다.

이번 글에서는 EXISTSIN 의 차이, 성능 비교 포인트, 그리고 실무에서 어떤 기준으로 선택하면 좋은지 쉽게 정리해보겠습니다.

EXISTS와 IN은 뭐가 다를까?
비슷해 보이지만, DB가 처리하는 관점은 조금 다릅니다.

먼저 예시부터 보겠습니다.

SELECT *
FROM orders o
WHERE o.customer_id IN (
  SELECT c.id
  FROM customer c
  WHERE c.status = 'ACTIVE'
);

이 쿼리는 활성 고객의 주문만 조회하는 예시입니다.

비슷한 의미를 EXISTS 로 바꾸면 이렇게 쓸 수 있습니다.

SELECT *
FROM orders o
WHERE EXISTS (
  SELECT 1
  FROM customer c
  WHERE c.id = o.customer_id
    AND c.status = 'ACTIVE'
);

둘 다 결과는 비슷할 수 있지만, 해석 방식은 다릅니다.

  • IN → 특정 값이 집합 안에 포함되는지 확인
  • EXISTS → 조건을 만족하는 행이 존재하는지 확인
쉽게 이해하면
IN 은 “이 값이 목록 안에 있나?”에 가깝고, EXISTS 는 “조건 맞는 게 하나라도 있나?”에 가깝습니다.
IN이 더 직관적인 경우
비교 대상이 작고, 의미가 값 목록 비교일 때는 IN이 읽기 쉽습니다.

예를 들어 특정 상태 코드만 조회하는 경우는 IN 이 아주 자연스럽습니다.

SELECT *
FROM orders
WHERE status IN ('READY', 'PAID', 'SHIPPED');

이건 서브쿼리도 아니고, 그냥 값 목록 비교이기 때문에 IN 이 훨씬 읽기 쉽습니다.

또 서브쿼리라도 결과 건수가 매우 작고 단순하면 IN 이 가독성 면에서 좋을 수 있습니다.

기억할 점
작은 목록 비교정적인 값 비교는 보통 IN이 더 직관적입니다.
EXISTS가 유리한 경우
존재 여부만 확인하면 되는 상황에서는 EXISTS가 더 잘 맞습니다.

EXISTS 는 서브쿼리 안에서 조건을 만족하는 행을 찾으면, 그 이후를 다 보지 않고 빠르게 판단할 수 있는 형태로 최적화되는 경우가 많습니다.

예를 들어 주문이 있는 고객만 찾고 싶다면:

SELECT *
FROM customer c
WHERE EXISTS (
  SELECT 1
  FROM orders o
  WHERE o.customer_id = c.id
);

이 경우 핵심은 주문 상세값이 아니라, 그 고객에게 주문이 하나라도 있느냐 입니다.

이럴 때는 IN 보다 EXISTS 가 의도도 더 명확하고, 실행계획상 유리한 경우가 많습니다.

실무 포인트
존재 여부만 필요하다면 EXISTS를 먼저 떠올리는 습관이 실무에서 꽤 유용합니다.
성능은 항상 EXISTS가 더 좋을까?
항상 그런 것은 아닙니다. 데이터 양과 실행계획에 따라 달라집니다.

많이 오해하는 부분이 바로 이것입니다.

  • EXISTS 가 무조건 빠르다
  • IN 은 무조건 느리다

이렇게 외우면 안 됩니다.

실제 성능은 아래 요소에 따라 달라집니다.

  • 서브쿼리 결과 건수
  • 인덱스 유무
  • 상관 서브쿼리 여부
  • 옵티마이저가 내부적으로 어떻게 변환했는지
  • DBMS 종류(MySQL, Oracle, PostgreSQL 등)

즉, 중요한 건 문법 이름보다 실행계획이 실제로 어떻게 잡히는가 입니다.

핵심 정리
EXISTS vs IN 은 문법 싸움이 아니라, 데이터 분포와 실행계획 싸움이라고 보는 게 더 정확합니다.
실무에서 자주 보는 성능 차이 포인트
아래 상황에서 성능 차이가 눈에 띄는 경우가 많습니다.

1) 서브쿼리 결과가 매우 클 때

IN 대상이 되는 결과 집합이 매우 크면 부담이 커질 수 있습니다. 이럴 때는 EXISTS 가 더 유리하게 보이는 경우가 많습니다.

2) 존재 여부만 중요할 때

실제로 필요한 건 “있다 / 없다” 뿐인데 값 목록 비교처럼 풀어 쓰면 비효율적일 수 있습니다.

3) 인덱스가 잘 잡혀 있을 때

EXISTS 안의 조인 조건 컬럼에 인덱스가 있으면 빠르게 존재 여부를 판단하기 좋습니다.

4) 옵티마이저가 내부적으로 세미조인(Semi Join) 형태로 최적화할 때

DBMS에 따라 INEXISTS 가 비슷하게 최적화되기도 합니다. 그래서 실제로는 생각보다 큰 차이가 안 날 수도 있습니다.

구분 IN EXISTS
의미 값이 집합 안에 포함되는지 확인 조건 만족 행이 존재하는지 확인
가독성 값 목록 비교에 직관적 존재 여부 판단에 직관적
자주 유리한 상황 작은 목록, 단순 비교 큰 데이터, 존재 여부 확인
실무 팁 간단하면 IN도 충분 성능 이슈 있으면 EXISTS 우선 검토
NULL 때문에 결과가 달라질 수 있다는 점도 중요하다
실무에서 의외로 자주 놓치는 포인트입니다.

특히 NOT INNULL 이 섞이면 예상과 다른 결과가 나올 수 있어서 주의해야 합니다.

예를 들어 서브쿼리 결과 안에 NULL 이 포함되면, NOT IN 비교가 의도대로 동작하지 않는 경우가 있습니다.

이럴 때는 NOT EXISTS 가 더 안전한 선택이 되는 경우가 많습니다.

SELECT *
FROM customer c
WHERE NOT EXISTS (
  SELECT 1
  FROM orders o
  WHERE o.customer_id = c.id
);
정말 중요한 포인트
NOT IN + NULL 조합은 실무에서 버그를 만들기 쉬우므로, 조건을 확실히 이해하고 써야 합니다.
그럼 실무에서는 어떻게 선택하면 될까?
아래 기준으로 판단하면 대부분 정리가 됩니다.

실무에서는 보통 이렇게 생각하면 쉽습니다.

  • 값 목록 비교가 핵심이면 IN
  • 존재 여부 판단이 핵심이면 EXISTS
  • 서브쿼리 결과가 크다EXISTS 우선 검토
  • NULL 이 걸릴 수 있는 부정 조건이면 NOT EXISTS 우선 검토
  • 최종 판단은 반드시 실행계획으로 확인
실무 한 줄 요약
존재 여부는 EXISTS, 작은 값 목록 비교는 IN 으로 먼저 생각하면 실수가 줄어듭니다.
마무리 정리
`EXISTS` 와 `IN` 은 결과만 비슷해 보일 뿐, 의미와 성능 포인트는 다를 수 있습니다. 무조건 어느 하나가 더 빠르다고 외우기보다, 값 비교인지 존재 여부 확인인지부터 구분하고 실행계획까지 함께 보는 습관이 중요합니다.
IN = 값이 집합 안에 있는지 비교
EXISTS = 조건 만족 행이 존재하는지 확인
성능 판단 기준 = 데이터 양 + 인덱스 + 실행계획
주의 포인트 = NOT IN 과 NULL 조합
실무 SQL은 문법을 외우는 것보다, 이 쿼리가 값을 비교하는지 존재를 확인하는지를 먼저 구분하는 습관이 더 중요합니다.
728x90
댓글
반응형
최근에 올라온 글
글 보관함
«   2026/04   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30