Search

REMINDER 11-04. NL JOIN에서 Driven 테이블의 반복 접근과 인덱스를 확인하자

⚠️
선택 심화 · 현재 보류: 이 페이지의 실행계획은 원문에 제시된 예상·개념적 예시이며 이번 PostgreSQL 실측 결과가 아닙니다. SQL/인덱스 설정은 검증 후 적용해야 합니다.
상황: PLAT·INV 회원과 2023-12-21~25 주문을 결합하여 회원별 주문금액을 합산한다.

BAD SQL — 비교 대상

-- 동일 SQL, 회원ID 조인 인덱스가 없거나 부적합한 상태 SELECT m.mbr_id, SUM(o.ord_amt) AS ord_amt FROM ms_mbr_big AS m JOIN tr_ord_big AS o ON o.mbr_id = m.mbr_id WHERE m.mbr_gd = 'PLAT' AND m.join_tp = 'INV' AND o.ord_dtm >= TIMESTAMP '2023-12-21' AND o.ord_dtm < TIMESTAMP '2023-12-26' GROUP BY m.mbr_id;
SQL
복사

GOOD SQL — 개선 후보

-- 인덱스 후보: 교재 [SQL-CRIX-TR_ORD_BIG_X11] -- CREATE INDEX tr_ord_big_x11 ON tr_ord_big (mbr_id); -- 동일 SELECT: 인덱스가 있을 때 반복 접근 비용 비교 SELECT m.mbr_id, SUM(o.ord_amt) AS ord_amt FROM ms_mbr_big AS m JOIN tr_ord_big AS o ON o.mbr_id = m.mbr_id WHERE m.mbr_gd = 'PLAT' AND m.join_tp = 'INV' AND o.ord_dtm >= TIMESTAMP '2023-12-21' AND o.ord_dtm < TIMESTAMP '2023-12-26' GROUP BY m.mbr_id;
SQL
복사
예상 실행계획 — 실측 아님
BAD (NL JOIN을 선택한 상황의 가능한 계획) GroupAggregate -> Nested Loop Join Filter: (o.mbr_id = m.mbr_id) -> 회원 집합 스캔 -> Materialize -> Seq Scan on tr_ord_big (날짜 Filter) → Materialize를 회원 행 수만큼 반복 조회할 수 있음 GOOD (NL JOIN + x11 선택 시) GroupAggregate -> Nested Loop -> 회원 집합 스캔 -> Index Scan using tr_ord_big_x11 on tr_ord_big Index Cond: (mbr_id = m.mbr_id) Filter: (ord_dtm >= ... AND ord_dtm < ...) → Driven 인덱스 검색이 외부 회원 수만큼 반복될 수 있음
Plain Text
복사

핵심

•
Nested Loop는 외부 집합(Driving)의 각 행을 기준으로 안쪽 집합(Driven)을 검색한다. Driven에 조인 컬럼 인덱스가 없으면 동일 데이터를 반복 확인할 위험이 있다.
원본 규칙: 개편 전 05-07.
💡
참고·예외
•
위 BAD 계획은 NL JOIN을 전제로 한 특정 시나리오다. 일반 SQL에는 pg_hint_plan 힌트가 없다면 PostgreSQL이 Hash Join 등을 선택할 수 있다. 원본 교재는 실제로 pg_hint_plan의 Leading/NestLoop 힌트를 써서 비교했으나, 여기서는 확장 설치 여부가 확인되지 않아 힌트를 SQL에 넣지 않았다.