EXISTS
VS
IN
SQL에서 EXISTS(혹은 NOT EXISTS)와 IN(혹은 NOT IN)은 서브쿼리를 이용해 어떤 조건을 만족하는지(주로 특정 테이블의 데이터가 다른 테이블에도 존재하는지) 확인한다는 점에선 비슷하지만 사용 목적과 동작 방식, 성능, NULL값 처리 등에서 몇가지 차이점이 있다.
1. 사용 목적의 차이
- <IN>
- 컬럼 값이 서브쿼리 결과집합(또는 명시된 집합)에 속하는지를 비교
- 컬럼 값 = 서브쿼리 결과집합 비교에 초점을 둔다
- 예시:
SELECT *
FROM TABLE_A
WHERE A.COL IN (SELECT B.COL FROM TABLE_B WHERE 조건);
- <EXISTS>
- 서브쿼리가 최소 한 행 이상 반환하는지(존재하는지)를 확인
- 상관(correlated) 서브쿼리에서 사용하며, 행의 ‘존재 여부’ 자체가 포인트
- 예시:
SELECT *
FROM TABLE_A A
WHERE EXISTS (
SELECT 1
FROM TABLE_B B
WHERE B.COL = A.COL
);
2. 동작 방식의 차이
- <IN>
- 집합(Set) 비교
- “A.COL이 이 값들 중 하나와 일치하는가?”를 서브쿼리 결과 전체에 대해 비교
- 서브쿼리 자체를 독립적으로 실행할 수 있고, 그 결과 집합이 외부 쿼리의 컬럼 값과 매칭되는지 확인
- <EXISTS>
- 서브쿼리의 ‘행 존재 여부’를 확인하여 서브쿼리에 행이 하나라도 존재하면 TRUE, 없으면 FALSE <- Boolean !
- 상관 서브쿼리로 외부 쿼리의 컬럼 값을 서브쿼리 안에서 직접 비교하며, “현재 외부 쿼리의 행이 서브쿼리에 들어가면 결과가 나오나?”를 확인
3. 성능의 차이
EXISTS는 조건을 만족하는 행이 하나라도 있을 경우 즉시 작동을 멈추고 TRUE를 반환하기 때문에 IN보다 적은 연산을 요해 더 좋은 성능을 나타낼 수도 있지만 데이터 양이나 인덱스, 쿼리에 따라 달라지기 때문에 반드시 EXISTS가 더 좋다고 할 순 없다. 특히 요즘엔 최적화 과정에서 실행 계획이 유사해져 큰 차이가 없는 경우도 있다 한다.
4. NULL값 처리 차이
- IN 구문에서 서브쿼리 결과 중에 NULL이 포함되어 있으면, 비교 실패가 발생할 수 있다. 특히 NOT IN에서 더 주의해야 하는데 NOT IN은 사실상 AND와 동일하게 작동하기 때문이다. 서브쿼리에 하나라도 NULL값이 있을 경우 'TRUE AND TRUE AND NULL'이 되어버려 결국엔 NULL이 반환되고 검색을 할 수 없다. 이를 방지하기 위해선 서브쿼리의 WHERE 절에 IS NOT NULL을 추가해야 한다.
- EXISTS는 행 존재 여부만 판단하므로, NULL 값 자체는 큰 영향 X
5. 정리
그때그때의 쿼리 작성 목적을 잘 판단하여 사용하면 될 것 같다.
집합(Set) 비교가 직관적으로 맞는가? → IN
존재 여부(특정 조건을 만족하는 행이 하나라도 있는지) 체크가 필요한가? → EXISTS
다중 행 서브쿼리의 다른 연산자가 궁금하다면 아래 글 참고!
2025.01.02 - [Oracle/공부] - [SQL] 다중 행 서브쿼리에서 ANY & ALL 연산자 사용
'Oracle > 공부' 카테고리의 다른 글
| [SQL] LEVEL을 이용해서 구구단 1단부터 9단까지 출력하기 (0) | 2025.01.07 |
|---|---|
| [SQL] MAX(COUNT())가 실행되지 않는 이유(집계함수, 윈도우함수) (1) | 2025.01.05 |
| [SQL] FROM 서브쿼리 별칭을 WHERE 서브쿼리에서 참조할 수 없는 이유 (2) | 2025.01.03 |
| [SQL] 다중 행 서브쿼리에서 ANY & ALL 연산자 사용 (1) | 2025.01.02 |
| [SQL] 컬럼 별칭(alias)을 부여할 때 주의해야 할 점 (1) | 2024.12.28 |