선택 심화 · 현재 보류: 이 페이지의 실행계획은 원문에 제시된 예상·개념적 예시이며 이번 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에 넣지 않았다.



