BAD: 13614.292ms, hit=2717, read=347937
전체 주문을 먼저 집계
SELECT t1.base_wkd
,t1.base_ymd
,t2.ord_amt_sum
FROM startdbpg.cm_base_dt t1
LEFT OUTER JOIN (
SELECT TO_CHAR(o.ord_dtm,'YYYYMMDD') ord_ymd
,SUM(o.ord_amt) AS ord_amt_sum
FROM startdbpg.tr_ord_big o
GROUP BY TO_CHAR(o.ord_dtm,'YYYYMMDD')
) t2
ON (t2.ord_ymd = t1.base_ymd)
WHERE t1.base_ymd LIKE '202401%'
ORDER BY t1.base_ymd
;
SQL
복사
실행계획 보기
•
바깥 조건(base_ymd)과 인라인 뷰 안의 컬럼(ord_dtm)이 서로 달라서, DB가 이 조건을 안쪽에 자동으로 넣어 주지 못합니다.
•
그래서 전체 주문 2,600만 건을 읽어 2,143일을 모두 집계한 뒤, 31일만 조인합니다.
GOOD: 384.388ms, hit=9231
필요한 날짜만 먼저 필터링
SELECT t1.base_wkd
,t1.base_ymd
,t2.ord_amt_sum
FROM startdbpg.cm_base_dt t1
LEFT OUTER JOIN (
SELECT TO_CHAR(o.ord_dtm,'YYYYMMDD') ord_ymd
,SUM(o.ord_amt) AS ord_amt_sum
FROM startdbpg.tr_ord_big o
WHERE o.ord_dtm >= '2024-01-01'
AND o.ord_dtm < '2024-02-01'
GROUP BY TO_CHAR(o.ord_dtm,'YYYYMMDD')
) t2
ON (t2.ord_ymd = t1.base_ymd)
WHERE t1.base_ymd LIKE '202401%'
ORDER BY t1.base_ymd
;
SQL
복사
실행계획 보기
•
인라인 뷰 안에 같은 기간 조건을 ord_dtm으로 직접 씁니다.
•
1월 주문 62만 건만 인덱스로 읽어 31일만 집계합니다(Index Cond).
KEY POINT
•
인라인 뷰 바깥의 조건은 안쪽에 자동으로 전달되지 않을 수 있습니다.
•
결과가 같다면, 조건을 인라인 뷰 안쪽(원본 테이블에 가까운 곳)에 직접 씁니다.
•
실행계획에서 원본 테이블을 몇 건 읽는지 확인합니다.
TIP. 조건을 옮기기 전에 확인할 것
•
조건을 안쪽으로 옮겨도 최종 결과가 같은지 먼저 확인합니다.
•
이 예제는 바깥 조건을 그대로 복사한 게 아니라, 같은 기간을 ord_dtm으로 바꿔 쓴 것입니다.
DEEP DIVE


