테마
한빛유통 본사와 매장의 대시보드(전광판 300대와 영업 화면)는 5분마다 집계 테이블 T_ORD_DASH를 읽어 화면을 새로 그린다. 집계 테이블은 스케줄러 잡이 5분마다 비우고 다시 채운다. 잡은 0.4초 만에 끝나는데, 잡이 끝난 직후 전광판이 한꺼번에 3~4초씩 멈추고 가끔은 숫자가 0으로 한 번 깜빡인다.
박팀장이 대안 셋을 들고 왔다. 개발팀은 임시 테이블(GTT)로 바꾸자고 하고, DBA는 테이블 두 개를 번갈아 채우고 시노님을 바꿔 끼우자고 하며, 오과장은 DELETE 후 INSERT로 바꾸자고 한다. "셋 중 무엇으로 갈지, 근거와 함께 오후까지 주세요."
T_ORD_DASH 대시보드 집계: T_ORD_BIG에서 최근 30일을 일자 × 고객 등급 × 상태로 묶은 것 · 270행 · 4블록 · PK (BS_DT, CUS_GD, ORD_ST)T_ORD_BIG: 1,000,000행 · 5,826블록 · M_CUS: 2,000행 · 30블록CURSOR_SHARING = EXACT-- 스케줄러 잡 DASH_REFRESH : 5분마다 (매시 0분, 5분, 10분 …)
PROCEDURE P_DASH_REFRESH(p_from DATE) IS
BEGIN
EXECUTE IMMEDIATE 'TRUNCATE TABLE T_ORD_DASH';
INSERT /*+ APPEND */ INTO T_ORD_DASH (BS_DT, CUS_GD, ORD_ST, ORD_CNT, ORD_AMT)
SELECT TRUNC(o.ORD_DT), c.CUS_GD, o.ORD_ST, COUNT(*), SUM(o.ORD_AMT)
FROM T_ORD_BIG o, M_CUS c
WHERE o.ORD_DT >= p_from
AND c.CUS_ID = o.CUS_ID
GROUP BY TRUNC(o.ORD_DT), c.CUS_GD, o.ORD_ST;
COMMIT;
END;
-- 대시보드 문장 셋 가운데 하나 (앞부분)
SELECT d.BS_DT, d.CUS_GD, SUM(d.ORD_AMT) AS ORD_AMT,
SUM(SUM(d.ORD_AMT)) OVER (PARTITION BY d.CUS_GD ORDER BY d.BS_DT) AS CUM_AMT
FROM T_ORD_DASH d
WHERE d.ORD_ST = :st
GROUP BY d.BS_DT, d.CUS_GD
UNION ALL
…
[V$SQLAREA · 18:00 · 대시보드 문장 셋 (09:00부터 누적)]
문장 EXECUTIONS LOADS INVALIDATIONS
등급별 누적 1,312,400 109 108
상태별 오늘 998,700 109 108
일자별 추이 986,100 109 108
[10046 → TKPROF · 등급별 누적 문장 · 잡이 끝난 직후 첫 실행]
Parse count 1 · cpu 0.78 · elapsed 0.81
Misses in library cache during parse: 1
[ASH · 10:05:00 ~ 10:05:05 · 초별 활성 세션]
초 cursor: pin S wait on X library cache lock CPU 합계
:00.4 0 3 2 5 ← TRUNCATE
:01 212 0 6 218
:02 196 0 5 201
:03 141 0 4 145
:04 12 0 3 15
[전광판 로그 · 10:05:00.2 ~ 10:05:00.6 에 읽은 화면] T_ORD_DASH 0건 → 매출 0으로 표시 (하루 30~40번)
[잡 한 번] 0.4초 · TRUNCATE 0.05초 + INSERT(APPEND) 0.33초 · redo 약 20KB