Search

REMINDER 10-07. 여러 번 참조하는 CTE에 각기 다른 조건을 공급하려면 NOT MATERIALIZED를 검토하자

⚠️
예상 실행계획 — 실측 아님: 이 항목의 실행계획은 검증된 PostgreSQL 측정값이 아닙니다.
상황: 2023년 3월, 두 회원 각각의 주문 건수를 구한다.

BAD SQL — MATERIALIZED 사용

WITH orders AS MATERIALIZED ( SELECT o.mbr_id, o.ord_no FROM tr_ord_big o WHERE o.ord_dtm >= TIMESTAMP '2023-03-01' AND o.ord_dtm < TIMESTAMP '2023-04-01' ) SELECT (SELECT COUNT(*) FROM orders WHERE mbr_id = 'M00019') AS cnt_19, (SELECT COUNT(*) FROM orders WHERE mbr_id = 'M00020') AS cnt_20;
SQL
복사

GOOD SQL — NOT MATERIALIZED 사용

WITH orders AS NOT MATERIALIZED ( SELECT o.mbr_id, o.ord_no FROM tr_ord_big o WHERE o.ord_dtm >= TIMESTAMP '2023-03-01' AND o.ord_dtm < TIMESTAMP '2023-04-01' ) SELECT (SELECT COUNT(*) FROM orders WHERE mbr_id = 'M00019') AS cnt_19, (SELECT COUNT(*) FROM orders WHERE mbr_id = 'M00020') AS cnt_20;
SQL
복사
예상 실행계획 — 실측 아님
BAD (가능한 형태) CTE orders -> tr_ord_big의 3월 주문 집합 스캔 Result -> Aggregate -> CTE Scan on orders (mbr_id = 'M00019') -> Aggregate -> CTE Scan on orders (mbr_id = 'M00020') GOOD (x04: mbr_id, ord_dtm 인덱스 선택 시) Result -> Aggregate -> Index Only Scan / Index Scan Index Cond: (mbr_id = 'M00019' AND ord_dtm 범위) -> Aggregate -> Index Only Scan / Index Scan Index Cond: (mbr_id = 'M00020' AND ord_dtm 범위) => 원본을 두 번 조회하지만 각 조회 범위가 작음
Plain Text
복사

핵심

•
MATERIALIZED는 계산 재사용에 유리할 수 있지만 상위 조건의 개별 전달을 막는다.
•
NOT MATERIALIZED는 참조마다 조건을 내부로 전달할 수 있다. 원본을 반복 조회하더라도 각 조회 범위가 매우 작아질 때 검토할 수 있다.
원본 규칙: 개편 전 08-04.
💡
참고·예외
•
NOT MATERIALIZED가 항상 빠른 것은 아니다. 대상 회원이 많거나 월간 CTE 자체가 작으면 한 번 읽어 재사용하는 편이 나을 수 있다. 이 예제에서 둘 다 결과적으로 동일한 두 COUNT 값을 반환한다.