테마
버거원 분석 DB는 매월 1일 01:00에 주문상품 전체를 DW 전송용 정제 테이블 DW_ORD_ITEM_CLN에 다시 담는다. 한 문장으로 3분 10초가 걸렸고, 01:30에 DW 전송이 시작되므로 데이터가 늘면 겹칠 것이 걱정이었다. 분석 DB는 Standard Edition 2라 병렬 쿼리와 병렬 DML을 쓸 수 없어서, 개발자가 작업 스케줄러로 작업 8개를 띄우고 ORA_HASH(ORD_NO, 7)로 행을 나눠 맡겼다.
이번 달 실행은 2분 31초였다. 개발자: "여덟 개로 나눴으면 30초 남짓이어야 하는데요." 그 시간 대기의 91%가 direct path read였다.
ORD_ITEM 주문상품: 2,472,717행 · 55,265블록(약 432MB) · ORD_ITEM_PK (ORD_NO, ITEM_ID) · ORD_ITEM_X01 (ORD_DT, ORD_HMS)DW_ORD_ITEM_CLN(정제 테이블, 이 문제용): 인덱스 · 제약 · 트리거 없음 · 적재 전에 TRUNCATE한다. 01:00 ~ 01:30에는 이 배치만 쓴다.CREATE JOB 권한이 있다(작업 스케줄러와 DBMS_PARALLEL_EXECUTE를 쓸 수 있다).-- 매월 1일 01:00 · 작업 8개 (k = 0 ~ 7) 가 각자 아래 문장을 실행하고 커밋한다
INSERT INTO DW_ORD_ITEM_CLN (ORD_NO, ITEM_ID, ORD_ITEM_QTY, ORD_DT, ORD_HMS, ORD_YM)
SELECT ORD_NO, ITEM_ID, NVL(ORD_ITEM_QTY, 0), ORD_DT, ORD_HMS, SUBSTR(ORD_DT, 1, 6)
FROM ORD_ITEM
WHERE ORA_HASH(ORD_NO, 7) = :k;
COMMIT;
[작업 하나 (k = 0) — DISPLAY_CURSOR(FORMAT => 'ALLSTATS LAST')]
------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
------------------------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 1 | | 0 |00:02:29.61 | 62414 | 55265 |
| 1 | LOAD TABLE CONVENTIONAL | DW_ORD_ITEM_CLN | 1 | | 0 |00:02:29.61 | 62414 | 55265 |
|* 2 | TABLE ACCESS FULL | ORD_ITEM | 1 | 24727 | 309K|00:02:18.20 | 55269 | 55265 |
------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(ORA_HASH("ORD_NO",7)=:K)
[작업 8개 — 스케줄러 기록과 세션 통계]
작업 시작 끝 넣은 행 physical reads
DW_CLN_0 01:00:02 01:02:31 309,412 55,265
DW_CLN_1 01:00:02 01:02:33 308,977 55,265
… … … … …
DW_CLN_7 01:00:02 01:02:32 309,106 55,265
합계 2,472,717 442,120 (한 문장으로 돌 때 55,265)
대기: direct path read 91% · CPU 8%