SQLP

시험 직전 요약장

판단 기준과 헷갈리는 개념, 대표 예제를 짧게 확인하세요.

이론 목록

상관 서브쿼리 FILTER 실행: Starts·조기 종료·Semi/Anti Join

원래 이론 →

판단 기준

혼동하기 쉬운 판단정확한 기준
상관 서브쿼리는 항상 Outer 행 수만큼 완전히 실행된다재사용·조기 종료·Transformation에 따라 실제 Starts와 작업량이 달라진다
실행계획의 FILTER는 모두 상관 서브쿼리다일반 Predicate 평가에도 사용되므로 하위 Row Source와 Predicate를 함께 본다
동일 Key가 반복되면 Subquery는 정확히 NDV만큼 실행된다Cache 충돌과 Plan 구조가 있으므로 실제 Starts로 확인한다
한 번의 Index Probe가 싸면 FILTER 전체도 싸다작은 비용도 수십만 번 반복되면 큰 총량이 된다
EXISTS 안의 SELECT 값이 NULL이면 FALSE다SELECT 값이 아니라 조건을 만족하는 행의 존재를 검사한다
Semi Join은 FILTER보다 항상 빠르다Outer 크기, Index Probe 비용, 첫 행·전체 처리 목표에 따라 달라진다
Starts는 Cache Miss 횟수다Row Source 시작 횟수이며 Cache Hit Counter가 아니다
FILTER 비용에 Outer Row 수와 Starts를 모두 곱한다Starts에 실제 반복 횟수가 이미 반영된다
Inner Match가 10건이면 Semi Join도 Outer를 10건 반환한다존재 판정이므로 Outer Row는 한 번만 반환
NULL 상관 Key끼리는 Equality로 Match한다NULL = NULL은 UNKNOWN이므로 명시적 Null-safe 조건 필요
Unnesting Hint가 있으면 항상 Join으로 변환된다의미적·구조적 제한과 Hint 적용 여부를 확인
A-Rows가 0이면 Inner Probe 비용도 0이다반환 Row가 없어도 Index·Table Block을 읽을 수 있다

이 부분의 원문 →

헷갈리는 개념

같은 존재 Query가 Unnesting되면 Semi Join 후보가 될 수 있습니다.

예시·텍스트
FILTER 방식
Outer Row마다 Subquery Probe

SEMI JOIN 방식
두 입력을 하나의 Join Graph에서 최적화
조건FILTER가 유리할 수 있는 상황Semi Join이 유리할 수 있는 상황
Outer 크기매우 작음큼
Inner Access단건 Index Probe대량 Scan·Hash 처리
첫 행 응답빠를 수 있음Build가 필요하면 늦을 수 있음
전체 처리반복 횟수가 적을 때반복 Probe를 집합 처리로 줄일 때
Join OrderOuter 중심으로 제한될 수 있음Subquery 쪽을 먼저 읽는 후보 가능

두 방식은 결과 의미가 같아도 비용 구조가 다릅니다.

Semi Join은 Inner에 Match Row가 여러 개 있어도 Outer Row를 한 번만 반환합니다.

도식
Outer 주문 1건
Inner Item Match 10건
→ SEMI JOIN 결과 Outer 주문 1건

일반 Inner Join은 별도 DISTINCT가 없으면 Outer Row가 Match 수만큼 증식할 수 있으므로 EXISTS를 단순 Join으로 수동 변경할 때 결과 Cardinality를 검증합니다.

Anti Join도 Match가 하나라도 발견되면 Outer Row를 제거하고 Inner 중복 수만큼 결과를 늘리지 않습니다.

NO_UNNEST와 기본 Plan을 제한적으로 비교해 FILTER 비용을 관찰할 수 있지만, Hint는 결과 의미를 정의하지 않으며 최종 판단은 Hint 없는 정상 Plan과 실제 업무 조건을 기준으로 합니다.


이 부분의 원문 →

대표 계산·예제

FILTER 방식의 기본 비용은 다음처럼 생각할 수 있습니다.

예시·텍스트
전체 비용
≈ Outer Row Source 생성 비용
 + 실제 Subquery 반복 작업량

실제 Subquery 반복 작업량
≈ Subquery Starts × Starts당 Inner 평균 작업량

Outer Row 수를 다시 곱하지 않습니다. Starts 자체가 실제 반복 시작 횟수를 이미 나타냅니다.

예를 들어 실행 통계가 다음과 같습니다.

예시·텍스트
ORDERS TABLE ACCESS       A-Rows = 1,000,000
CUSTOMER Subquery Root    Starts =   950,000
CUSTOMER Index Scan       Buffers = 2,850,000

Subquery가 거의 Outer 행 수만큼 시작됐고, Index Scan에서 약 285만 Buffer를 사용했습니다.

예시·텍스트
1회 평균 Buffer
≈ 2,850,000 ÷ 950,000
≈ 3 Blocks

한 번의 Probe가 3 Buffer로 작아 보여도 95만 번 반복되면 전체 부하는 큽니다.

A-Rows와 Buffers는 Plan Row Source에서 누적값으로 표시될 수 있으므로 다음 평균을 함께 계산합니다.

예시·텍스트
Starts당 Inner 반환 Row
= Inner A-Rows ÷ Subquery Starts

Starts당 Inner Buffer
= Inner Buffers ÷ Subquery Starts

다만 A-Rows=0이어도 Index Block을 여러 개 읽을 수 있으므로 반환 Row 수만으로 Probe 비용을 판단하지 않습니다.

반대로 Outer 1,000행, Subquery Starts 20, Inner Buffers 60이라면 반복 Key 재사용이나 다른 최적화로 실제 Subquery 작업량이 매우 작을 수 있습니다.


이 부분의 원문 →

내 최근 연습 오답

현재 브라우저의 연습 채점 기록에서 공개된 단원과 연결된 오답을 확인합니다.

학습 기록 →

오답 기록을 확인하고 있습니다.