테마
일요일 22:00 야간 체인은 네 단계다. 오과장이 체인을 정리하면서 ① 뒤의 통계 수집 단계를 뺐고("APPEND가 알아서 모은다"), 대신 체인 맨 앞(21:50)에 GATHER_SCHEMA_STATS 한 줄을 넣었다("한 번에 다 모으자").
월말과 일요일이 겹친 6월 30일 밤 ④ 재처리가 15초 가까이 걸렸고, 7월 1일 월요일 09:00 정산팀의 「6월 취소 주문」 조회가 지난주보다 열 배 무거워졌다. 박팀장: "통계 정책을 체인 단위로 다시 짜 주세요. 테이블마다 언제, 어떻게, 왜."
T_ORD_BIG: 1,000,000행 · 5,826블록 · 매주 일요일 재적재(원천 STG_ORD_BIG) · 인덱스 IX_ORD_BIG_DT_AMT (ORD_DT, ORD_AMT) · IX_ORD_BIG_ST_DT (ORD_ST, ORD_DT)(클러스터링 팩터 약 99만) · 선호도 FOR ALL COLUMNS SIZE 1 FOR COLUMNS SIZE 254 ORD_ST(정책서 1호)T_ORD_STLM: 100,000행 · 640블록 · 인덱스 없음 · 체인마다 비우고 다시 싣는다 · 히스토그램이 필요한 열 없음W_STLM_ERR 정산 오류 작업 테이블(이 문제용): ORD_SEQ · ERR_CD · 평소 0 ~ 300행, 월말 약 20,000행(64블록) · 인덱스 없음 · 체인 끝에 DELETE로 비운다T_ORD: 100,000행 · 896블록 · PK_T_ORD · V_STLM_CHECK는 정산과 주문을 견주는 점검 뷰다.GT_CUS_PICK: 상담 화면의 전역 임시 테이블 · 통계 없음 · M_CUS · M_RGN · M_ITM은 거의 바뀌지 않는다.-- 일요일 21:50 · 야간 체인 (오과장 정리판)
BEGIN
-- "한 번에 다 모으자"
DBMS_STATS.GATHER_SCHEMA_STATS(ownname => USER, no_invalidate => FALSE);
-- ① T_ORD_BIG 재적재 (통계 수집 단계는 뺐다 : "APPEND 가 알아서 모은다")
EXECUTE IMMEDIATE 'TRUNCATE TABLE T_ORD_BIG';
INSERT /*+ APPEND */ INTO T_ORD_BIG (ORD_SEQ, CUS_ID, ORD_DT, ORD_ST, ORD_AMT)
SELECT ORD_SEQ, CUS_ID, ORD_DT, ORD_ST, ORD_AMT FROM STG_ORD_BIG;
COMMIT;
-- ② T_ORD_STLM 정산 적재
EXECUTE IMMEDIATE 'TRUNCATE TABLE T_ORD_STLM';
INSERT /*+ APPEND */ INTO T_ORD_STLM (STLM_SEQ, ORD_SEQ, CUS_ID, STLM_DT, STLM_AMT)
SELECT ROWNUM, ORD_SEQ, CUS_ID, ORD_DT, ORD_AMT FROM T_ORD;
COMMIT;
-- ③ 정산 오류 건 (평소 0 ~ 300행 · 월말 약 20,000행)
INSERT INTO W_STLM_ERR (ORD_SEQ, ERR_CD)
SELECT ORD_SEQ, ERR_CD FROM V_STLM_CHECK;
COMMIT;
-- ④ 재처리 → 비우기
UPDATE T_ORD_STLM s
SET s.STLM_AMT = (SELECT o.ORD_AMT FROM T_ORD o WHERE o.ORD_SEQ = s.ORD_SEQ)
WHERE s.ORD_SEQ IN (SELECT e.ORD_SEQ FROM W_STLM_ERR e);
COMMIT;
DELETE FROM W_STLM_ERR;
COMMIT;
END;
[USER_TAB_STATISTICS — 7월 1일(월) 09:00]
TABLE_NAME NUM_ROWS LAST_ANALYZED 비고
T_ORD_BIG 1,000,000 일 22:04 NOTES = STATS_ON_LOAD · ORD_ST HISTOGRAM NONE
T_ORD_STLM 100,000 일 22:06 NOTES = STATS_ON_LOAD
W_STLM_ERR 0 일 21:51 (체인 맨 앞의 GATHER_SCHEMA_STATS)
T_ORD 100,000 일 21:50
M_CUS 2,000 일 21:50
[A] 7월 1일(월) 09:00 · 「6월 취소 주문」
SELECT ORD_SEQ, CUS_ID, ORD_DT, ORD_AMT FROM T_ORD_BIG
WHERE ORD_ST = 'CANCEL' AND ORD_DT >= DATE '2024-06-01' AND ORD_DT < DATE '2024-07-01'
---------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
---------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 549 |00:00:00.06 | 5826 |
|* 1 | TABLE ACCESS FULL| T_ORD_BIG | 1 | 9445 | 549 |00:00:00.06 | 5826 |
---------------------------------------------------------------------------------------
1 - filter(("ORD_ST"='CANCEL' AND "ORD_DT">=TO_DATE(' 2024-06-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss')
AND "ORD_DT"<TO_DATE(' 2024-07-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss')))
(지난주 같은 조회 · ORD_ST FREQUENCY 가 있을 때 : E-Rows 567 · IX_ORD_BIG_ST_DT 범위 스캔 · Buffers 556)
[B] 6월 30일(일) 23:40 · ④ 재처리 (월말 · 오류 20,000건)
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
----------------------------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 1 | | 0 |00:00:14.82 | 12M |
| 1 | UPDATE | T_ORD_STLM | 1 | | 0 |00:00:14.82 | 12M |
| 2 | NESTED LOOPS | | 1 | 1 | 20000 |00:00:14.60 | 12M |
| 3 | SORT UNIQUE | | 1 | 1 | 20000 |00:00:00.02 | 64 |
| 4 | TABLE ACCESS FULL | W_STLM_ERR | 1 | 1 | 20000 |00:00:00.01 | 64 |
|* 5 | TABLE ACCESS FULL | T_ORD_STLM | 20000 | 1 | 20000 |00:00:14.55 | 12M |
| 6 | TABLE ACCESS BY INDEX ROWID| T_ORD | 20000 | 1 | 20000 |00:00:00.05 | 40000 |
|* 7 | INDEX UNIQUE SCAN | PK_T_ORD | 20000 | 1 | 20000 |00:00:00.03 | 20000 |
----------------------------------------------------------------------------------------------
5 - filter("S"."ORD_SEQ"="E"."ORD_SEQ")
7 - access("O"."ORD_SEQ"=:B1)
T_ORD_BIG, T_ORD_STLM, W_STLM_ERR, 마스터, GT_CUS_PICK) 통계를 언제 어떻게 모을지 정하고, 고친 체인을 쓰시오.