개발/ETC

SQL에서 NOT IN 쓰다 피본 적 있다면 꼭 알아야 할 내용

devhooney 2025. 5. 30. 08:31
728x90

 

 

NOT IN 쿼리를 사용 시 발생할 수 있는 문제가 있다.

 

 

 

✅ NOT IN 사용 시 발생할 수 있는 문제

 

1. NULL 포함 시 결과 이상

NOT IN 대상 컬럼에 NULL이 포함되면 전체 결과가 비어버릴 수 있음

예시:

SELECT * FROM users WHERE id NOT IN (1, 2, NULL);

 

이 경우 아무 결과도 반환되지 않음 (NULL은 비교 불가하기 때문)

✔️ 해결: NOT IN을 쓰기 전에 NULL 값을 필터링해야 함

SELECT * FROM users WHERE id NOT IN (
    SELECT id FROM blacklisted WHERE id IS NOT NULL
);

 

 

 

2. 성능 저하

NOT IN (SELECT ...)은 서브쿼리 결과를 모든 행마다 비교 → 인덱스가 있어도 잘 사용되지 않음
특히 대상 테이블이 크거나 조인 없이 서브쿼리를 사용할 경우 Full Scan 발생

 

 

 

 

728x90

 

 

 

 

✅ NOT IN 대신 고려할 수 있는 대안

 

1. NOT EXISTS 사용

SELECT * FROM users u
WHERE NOT EXISTS (
  SELECT 1 FROM blacklisted b WHERE b.id = u.id
);

 

장점
서브쿼리에서 NULL이 있어도 안전
옵티마이저가 EXISTS를 빠르게 중단(short-circuit) 처리 가능
인덱스 활용률이 높음 (특히 서브쿼리 대상에 인덱스 있을 경우)

 

 

2. LEFT JOIN ... IS NULL 방식

SELECT u.*
FROM users u
LEFT JOIN blacklisted b ON u.id = b.id
WHERE b.id IS NULL;

 

장점
가독성이 좋고 조인 대상 인덱스를 잘 타는 경우도 있음
NOT EXISTS와 비슷한 동작

단점
조인 성능이 떨어질 수 있고, 중복 row 주의 필요

 

 

 

 

3. 서브쿼리 결과를 WITH로 미리 정리

WITH valid_blacklist AS (
  SELECT id FROM blacklisted WHERE id IS NOT NULL
)
SELECT * FROM users
WHERE id NOT IN (SELECT id FROM valid_blacklist);

 

WITH 절을 통해 가독성과 재사용성 향상
경우에 따라 옵티마이저가 성능 개선 적용 가능

 

728x90

'개발 > ETC' 카테고리의 다른 글

SQL 인젝션  (88) 2025.05.22
템플릿 메소드 패턴  (86) 2025.05.20
NoSQL DB 종류 알아보기  (39) 2025.05.18
결합도 공부  (67) 2025.05.08
이진 트리 공부  (74) 2025.04.30