EXISTS와 IN의 성능 비교
EXISTS가 일찍 검색을 중단해 IN보다 빠른 경우를 알아봅니다. 고급 면접에서 자주 나오는 질문입니다.
EXISTS와 IN의 성능 비교은(는) CoddyKit의 무료 Coding Interview Prep 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Coding Interview Prep 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Coding Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.
EXISTS가 실제로 검사하는 것
EXISTS는 서브쿼리를 받아 서브쿼리가 하나 이상의 행을 생성하는 순간 참을 반환합니다. 반환된 값이 무엇인지는 중요하지 않고, 행이 하나라도 존재하는지만 확인합니다.
- 이는
WHERE에서 사용하는 불리언 검사입니다. - 대부분 상관된 형태로 사용됩니다. 내부 쿼리가 외부 행을 참조합니다.
이 한 가지 질문은 거의 모든 중급~고급 SQL 면접에 등장합니다.
기본 EXISTS 쿼리
주문을 하나 이상 등록한 고객을 찾습니다. 내부 쿼리는 o.customer_id = c.id를 통해 외부 쿼리와 상관되며, 일치하는 주문을 하나 찾는 즉시 EXISTS가 참을 반환합니다.
SELECT 1에 주목하십시오. 선택된 값은 중요하지 않으므로 대부분의 개발자는 1 또는 *를 작성합니다. 면접관은 어느 쪽이든 인정하며, 최적화기는 EXISTS 내부의 선택 목록을 무시합니다.
SELECT c.name
FROM customers c
WHERE EXISTS (
SELECT 1 FROM orders o
WHERE o.customer_id = c.id
);단락 평가 동작
면접관이 듣고 싶어 하는 핵심 단어는 단락 평가입니다. EXISTS는 일치하는 행을 하나 찾는 즉시 내부 쿼리 탐색을 멈춥니다. 일치하는 항목의 전체 목록을 만들거나 중복을 제거할 필요가 전혀 없습니다.
반면 IN은 개념적으로 서브쿼리에서 값 집합을 구체화한 뒤 포함 여부를 확인합니다. 내부 집합이 크거나 중복이 많으면 이 차이가 중요합니다.
동일한 쿼리를 IN으로 작성하기
다음은 주문이 있는 고객을 찾는 쿼리를 IN으로 작성한 형태입니다. 논리적으로는 결과가 같지만 동작 방식은 다릅니다. 서브쿼리는 비상관 쿼리이며, 외부 쿼리가 확인할 고객 ID 목록을 생성합니다.
최신 최적화기에서는 두 쿼리가 동일한 실행 계획을 만드는 경우가 많습니다 — 하지만 크고 중복이 많은 orders에서는 EXISTS가 첫 번째 일치 항목에서 멈출 수 있으므로 더 빠를 수 있습니다.
SELECT c.name
FROM customers c
WHERE c.id IN (
SELECT o.customer_id FROM orders o
);NOT EXISTS가 NOT IN보다 낫습니다
이것이 이 전체 과정의 핵심입니다. NOT EXISTS는 안티 조인을 표현하는 안전한 방법입니다. NOT IN과 달리 내부 쿼리에 NULL이 있어도 문제가 생기지 않습니다.
orders.customer_id에 NULL이 포함되어 있어도 주문이 없는 모든 고객을 안정적으로 찾습니다.
SELECT c.name
FROM customers c
WHERE NOT EXISTS (
SELECT 1 FROM orders o
WHERE o.customer_id = c.id
);NOT EXISTS가 NULL에 안전한 이유
NOT EXISTS는 상관된 서브쿼리가 일치하는 행을 찾았는가?라는 질문만 하므로 결과가 명확한 참 또는 거짓으로 나뉩니다. NULL인 customer_id는 o.customer_id = c.id를 절대 만족하지 않으므로 일치하지도 않고 논리를 오염시키지도 않습니다.
NOT IN에서는 목록의 NULL이 UNKNOWN을 만들어 모든 행을 제거하는 것과 대조됩니다. 이것이 고급 면접관들이 안티 조인에 NOT EXISTS를 선호하는 이유입니다.
IN이 실제로 더 나은 경우
균형 있게 판단해야 합니다 — IN이 항상 더 나쁜 것은 아닙니다. 서브쿼리가 작고, 고정되어 있으며, 중복이 없는 목록을 반환할 때는 IN이 명확하고 빠릅니다:
- 직접 지정한 값 몇 개 또는 아주 작은 조회 테이블
- 최적화기가 한 번 실행한 뒤 결과를 저장해 재사용할 수 있는 비상관 쿼리
아래 쿼리는 완전히 자연스러운 작성 방식이며, 이 경우 EXISTS를 선택하는 것은 과도하게 복잡하게 만드는 일입니다.
SELECT name
FROM products
WHERE category_id IN (
SELECT id FROM categories WHERE active = true
);현대적인 솔직한 답변
성숙한 최적화기(포스트그레스, 최신 SQL 서버 및 MySQL)는 IN과 EXISTS를 동일한 세미 조인 실행 계획으로 다시 작성하는 경우가 많습니다. 따라서 일반적인 양의 포함 여부 검사에서는 성능이 동일한 경우가 많습니다.
그래도 중요한 차이는 다음과 같습니다:
NOT IN과NOT EXISTS의 차이 — NULL이 있을 때의 정확성 문제입니다. 단순한 속도 문제가 아닙니다.- 매우 크거나 색인이 없는 내부 테이블 — EXISTS는 단락 평가를 수행합니다.
존재 여부를 위한 EXISTS와 JOIN 비교
면접관이 제기하는 또 다른 관점은 다음과 같습니다. 왜 그냥 JOIN을 사용하지 않을까요? 존재 여부만 확인하는 조인은 오른쪽에 중복이 있을 때 행을 여러 개로 늘릴 수 있으므로 DISTINCT가 필요해질 수 있습니다. EXISTS는 외부 행을 절대 중복하지 않습니다.
따라서 순수하게 존재 여부만 확인할 때는 JOIN ... DISTINCT보다 EXISTS가 더 깔끔합니다. 다른 테이블의 열이 실제로 필요할 때는 조인을 사용하십시오.
SELECT DISTINCT c.name
FROM customers c
JOIN orders o ON o.customer_id = c.id;색인이 성패를 좌우합니다
색인 없이는 성능에 대한 답변이 완전하지 않습니다. 상관된 EXISTS는 외부 행마다 내부 조회를 실행하므로, 상관 관계에 사용되는 열에 색인을 두는 것이 중요합니다 — 여기서는 orders(customer_id)입니다.
"서브쿼리가 상관 관계를 맺는 조인 열에 색인을 설정하겠습니다"라고 말하면 교과서적인 답변이 면접관이 존중하는 실용적인 답변으로 바뀝니다.
CREATE INDEX idx_orders_customer_id
ON orders (customer_id);면접용 핵심 답변
다음과 같이 말하십시오: "EXISTS는 첫 번째 일치 행에서 단락 평가를 수행하는 상관된 불리언 검사인 반면, IN은 값 목록의 포함 여부를 확인합니다. 양의 조건 검사에서는 최신 최적화기가 동일한 세미 조인 실행 계획을 만드는 경우가 많습니다. 실제 차이는 NOT EXISTS와 NOT IN의 차이입니다. NOT EXISTS는 NULL에 안전하므로 안티 조인에는 이를 선호하며, 상관된 열에 색인이 있는지 확인합니다."
간단한 확인
EXISTS와 IN 비교의 핵심입니다.
복습
EXISTS와 IN, 완벽히 정리:
EXISTS는 첫 번째 일치 행에서 단락 평가를 수행하는 상관된 불리언 조건이며, 내부의 선택 목록은 중요하지 않습니다.IN은 값 집합의 포함 여부를 확인하며, 작고 중복이 없고 비상관적인 목록에 적합합니다.- 양의 조건 검사에서는 최신 최적화기가 동일한 세미 조인 실행 계획을 선택하는 경우가 많습니다.
- 안티 조인에는
NOT IN보다NOT EXISTS를 선호하십시오 — NULL에 안전합니다. 상관된 열에 색인을 설정하십시오.
이로써 서브쿼리 심화 과정이 끝납니다.
AI 튜터와 함께 Coding Interview Prep을(를) 배우세요 — 무료
브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.
- 코스
- 90
- 레슨
- 360
자주 묻는 질문
“EXISTS와 IN의 성능 비교” 강의는 무료인가요?
네 — “EXISTS와 IN의 성능 비교” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Coding Interview Prep 강의 전체를 잠금 해제할 수 있습니다. Coding Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.
“EXISTS와 IN의 성능 비교”에서 뭘 배우나요?
EXISTS가 일찍 검색을 중단해 IN보다 빠른 경우를 알아봅니다. 고급 면접에서 자주 나오는 질문입니다. 브라우저에서 직접 실행하는 실습 코드로 Coding Interview Prep을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Coding Interview Prep을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Coding Interview Prep은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.
“EXISTS와 IN의 성능 비교” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Coding Interview Prep 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Coding Interview Prep 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- SELECT와 WHERE의 스칼라 하위 쿼리
- FROM 절의 하위 쿼리(파생 표)
- IN, ANY와 ALL 하위 쿼리
- EXISTS와 IN의 성능 비교