Search

[권장:성능]대량 행에 CASE 반복 계산

테이블을 여러 번 읽는 것보다는 SUM(CASE)로 한 번 읽는 게 낫습니다([권장:성능]중복 집계 인라인 뷰 (2번 예제 재검토)). 여기서 한 단계 더 나아가, 한 번 읽더라도 CASE 계산 횟수를 줄일 수 있습니다.

BAD: 624.306ms, hit=9134, read=0

전체 주문에 CASE를 반복 적용
SELECT SUM(CASE WHEN EXTRACT(DOW FROM o.ord_dtm) = 0 THEN o.ord_amt END) sun ,SUM(CASE WHEN EXTRACT(DOW FROM o.ord_dtm) = 1 THEN o.ord_amt END) mon ,SUM(CASE WHEN EXTRACT(DOW FROM o.ord_dtm) = 2 THEN o.ord_amt END) tue ,SUM(CASE WHEN EXTRACT(DOW FROM o.ord_dtm) = 3 THEN o.ord_amt END) wed ,SUM(CASE WHEN EXTRACT(DOW FROM o.ord_dtm) = 4 THEN o.ord_amt END) thu ,SUM(CASE WHEN EXTRACT(DOW FROM o.ord_dtm) = 5 THEN o.ord_amt END) fri ,SUM(CASE WHEN EXTRACT(DOW FROM o.ord_dtm) = 6 THEN o.ord_amt END) sat FROM startdbpg.tr_ord_big o WHERE o.ord_dtm >= '2024-01-01' AND o.ord_dtm < '2024-02-01' ;
SQL
복사
실행계획 보기
SQL 결과 보기
•
주문 628,272건마다 요일 계산(EXTRACT)과 CASE를 7번씩 합니다. 약 440만 번(628,272 × 7)입니다.

GOOD: 287.450ms, hit=9134, read=0

요일별 선집계 후 CASE로 컬럼 전환
SELECT MAX(CASE WHEN t1.day_of_wk = 0 THEN t1.ord_amt_sum END) sun ,MAX(CASE WHEN t1.day_of_wk = 1 THEN t1.ord_amt_sum END) mon ,MAX(CASE WHEN t1.day_of_wk = 2 THEN t1.ord_amt_sum END) tue ,MAX(CASE WHEN t1.day_of_wk = 3 THEN t1.ord_amt_sum END) wed ,MAX(CASE WHEN t1.day_of_wk = 4 THEN t1.ord_amt_sum END) thu ,MAX(CASE WHEN t1.day_of_wk = 5 THEN t1.ord_amt_sum END) fri ,MAX(CASE WHEN t1.day_of_wk = 6 THEN t1.ord_amt_sum END) sat FROM ( SELECT EXTRACT(DOW FROM o.ord_dtm) day_of_wk ,SUM(o.ord_amt) 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 EXTRACT(DOW FROM o.ord_dtm) ) t1 ;
SQL
복사
실행계획 보기
SQL 결과 보기
•
요일 계산은 주문마다 한 번씩만 하고(628,272번), 요일별로 먼저 합산해 7행으로 줄입니다. CASE는 7행 × 7 = 49번만 합니다.
•
요일별로 이미 1행이므로 MAX는 해당 요일의 합계 금액을 꺼내는 역할입니다.
•
읽은 양(hit 9,134)은 같습니다. 줄어든 건 계산 횟수입니다.
💡

KEY POINT

•
대량 행에 CASE를 여러 개 쓰면, 행 수 × CASE 개수만큼 계산이 반복됩니다.
•
GROUP BY로 먼저 집계해 행을 줄인 뒤, CASE로 컬럼을 나눕니다.
•
읽는 양이 같아도 계산 횟수가 줄면 빨라집니다.
✏️

TIP. 언제 효과가 큰가?

•
CASE가 2~3개이거나 대상 행이 적으면 차이가 거의 없습니다.
•
행이 많고 CASE가 많을수록(이 예제는 62만 건 × 7개) 효과가 큽니다.
📖 DEEP DIVE — SQL STARTER for MySQL