테마
정산팀 야간 배치 「클레임 취소 정산」은 01:20에 클레임 시스템에서 받은 고객 목록을 W_CLM_CUS에 싣고 바로 통계를 모은 뒤, 01:30에 그 고객들의 취소 주문을 T_CLM_STLM에 넣는다. 배치 로그를 보면 이 INSERT가 어떤 밤은 0.12초, 어떤 밤은 0.38초다. 지난주 오과장이 빨랐던 10월 3일의 계획을 AWR에서 꺼내 베이스라인으로 올렸지만, 그 뒤로도 느린 밤이 그대로 나온다.
배치 프레임워크는 장애 때 어느 실행의 SQL인지 찾으려고 모든 SQL 앞에 추적 주석을 붙여 보낸다(2024년 2월에 넣었다). 박팀장은 고칠 방법을 견줘 달라고 했다.
W_CLM_CUS(작업 테이블 · M_CUS에서 파생): 매일 밤 비우고 다시 싣는다 · 40 ~ 300명 · 1 ~ 2블록 · 적재 직후 통계 수집T_ORD_BIG: 1,000,000행 · 5,826블록 · ORD_ST에 FREQUENCY 히스토그램(CANCEL 2%) · IX_ORD_BIG_CUS_ST (CUS_ID, ORD_ST)T_CLM_STLM(정산 클레임 · T_ORD_STLM과 같은 꼴): 인덱스 없음 · 날마다 2만 건 안팎이 쌓인다-- 배치 프레임워크의 SQL 실행부 (모든 단계가 이 프로시저로 SQL 을 보낸다)
PROCEDURE RUN_STEP(p_job VARCHAR2, p_step VARCHAR2, p_body VARCHAR2) IS
v_sql VARCHAR2(32767);
BEGIN
v_sql := '/* JOB=' || p_job || ' STEP=' || p_step
|| ' RUN=' || TO_CHAR(SYSDATE, 'YYYYMMDD-HH24MISS') || ' */ ' || p_body;
EXECUTE IMMEDIATE v_sql;
END;
-- 단계 02 의 본문 (p_body)
INSERT INTO T_CLM_STLM (CLM_DT, CUS_ID, ORD_SEQ, ORD_DT, ORD_AMT)
SELECT TRUNC(SYSDATE), o.CUS_ID, o.ORD_SEQ, o.ORD_DT, o.ORD_AMT
FROM W_CLM_CUS w, T_ORD_BIG o
WHERE o.CUS_ID = w.CUS_ID
AND o.ORD_ST = 'CANCEL'
[DBA_HIST_SQLSTAT · 단계 02 INSERT · 밤마다]
날짜 SQL_ID EXACT_MATCHING_SIGNATURE PLAN_HASH_VALUE 클레임 고객 BUFFER_GETS ELAPSED
10-03 1a7k2c9x0m4qd 15226180973381201537 4190263358 300 6,479 0.12초
10-04 9cd3v8n1q7w2s 8703361925470018214 2385510647 40 20,813 0.38초
10-05 3mq0x6k2c8v1b 11902485617730264401 4190263358 180 6,477 0.12초
10-06 6tz8d1w4k9c0n 2648100733152846627 2385510647 40 20,813 0.38초
· 밤마다 SQL_ID와 서명이 다르다. V$SQL의 SQL_TEXT 앞부분: /* JOB=CLM_STLM STEP=02 RUN=20251006-013000 */ INSERT INTO T_CLM_STLM …
[DBA_SQL_PLAN_BASELINES] 10-07 09:10 오과장이 LOAD_PLANS_FROM_AWR로 올림 · SQL_ID 1a7k2c9x0m4qd · PLAN_HASH_VALUE 4190263358
SIGNATURE 15226180973381201537 · ENABLED YES · ACCEPTED YES · LAST_EXECUTED (없음)
[느린 밤 · 10-06 · 클레임 고객 40명]
Plan hash value: 2385510647
----------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
----------------------------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 1 | | 0 |00:00:00.38 | 20813 |
| 1 | LOAD TABLE CONVENTIONAL | T_CLM_STLM | 1 | | 0 |00:00:00.38 | 20813 |
| 2 | NESTED LOOPS | | 1 | 400 | 20000 |00:00:00.29 | 20163 |
| 3 | TABLE ACCESS FULL | W_CLM_CUS | 1 | 40 | 40 |00:00:00.01 | 3 |
| 4 | TABLE ACCESS BY INDEX ROWID BATCHED| T_ORD_BIG | 40 | 10 | 20000 |00:00:00.27 | 20160 |
|* 5 | INDEX RANGE SCAN | IX_ORD_BIG_CUS_ST | 40 | 10 | 20000 |00:00:00.01 | 160 |
----------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("O"."CUS_ID"="W"."CUS_ID" AND "O"."ORD_ST"='CANCEL')
[빠른 밤 · 10-03 · 클레임 고객 300명]
Plan hash value: 4190263358
-----------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Used-Mem |
-----------------------------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 1 | | 0 |00:00:00.12 | 6479 | |
| 1 | LOAD TABLE CONVENTIONAL | T_CLM_STLM | 1 | | 0 |00:00:00.12 | 6479 | |
|* 2 | HASH JOIN | | 1 | 3000 | 20000 |00:00:00.09 | 5829 | 1491K (0)|
| 3 | TABLE ACCESS FULL | W_CLM_CUS | 1 | 300 | 300 |00:00:00.01 | 3 | |
|* 4 | TABLE ACCESS FULL | T_ORD_BIG | 1 | 20000 | 20000 |00:00:00.08 | 5826 | |
-----------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("O"."CUS_ID"="W"."CUS_ID")
4 - filter("O"."ORD_ST"='CANCEL')