테마
본사 레거시 유통은 매주 일요일 01:10에 판매상품 CF11을 분석용 사본 CF11_DW로 통째로 다시 옮긴다. 지난주 배치 담당자가 교재 14화를 보고, 인덱스를 모두 끄고 직접 경로로 넣은 뒤 다시 짓도록 프로시저를 바꿨다.
일요일 스케줄러 기록은 「SUCCEEDED」였는데, 월요일 09:00 MD팀 분석 화면이 전부 0건으로 나왔다. MD팀: "지난주 판매가 하나도 없대요."
CF11 판매상품: 1,096,708행 · 8,204블록 · CF11_PK (SLE_NO, ITM_NO)CF11_DW 분석용 사본(문제 설정, CF11과 같은 컬럼): 기본 키 CF11_DW_PK (SLE_NO, ITM_NO)(제약이 만든 유니크 인덱스, 리프 약 4,500블록) · 일반 인덱스 CF11_DW_X01 (ITM_NO)(리프 약 2,400블록) · FK와 트리거는 없다.skip_unusable_indexes는 기본값 TRUE다. LOG_MSG는 로그 테이블에 한 줄을 남기는 자율 트랜잭션 프로시저다.PROCEDURE P_CF11_DW_LOAD IS
BEGIN
EXECUTE IMMEDIATE 'TRUNCATE TABLE CF11_DW';
EXECUTE IMMEDIATE 'ALTER INDEX CF11_DW_PK UNUSABLE';
EXECUTE IMMEDIATE 'ALTER INDEX CF11_DW_X01 UNUSABLE';
INSERT /*+ APPEND */ INTO CF11_DW (SLE_NO, ITM_NO, SLE_QTY, SLE_UPRC)
SELECT SLE_NO, ITM_NO, SLE_QTY, SLE_UPRC FROM CF11;
COMMIT;
EXECUTE IMMEDIATE 'ALTER INDEX CF11_DW_PK REBUILD';
EXECUTE IMMEDIATE 'ALTER INDEX CF11_DW_X01 REBUILD';
LOG_MSG('P_CF11_DW_LOAD', '적재 완료');
EXCEPTION
WHEN OTHERS THEN
EXECUTE IMMEDIATE 'ALTER INDEX CF11_DW_PK REBUILD'; -- 인덱스는 살려 둔다
EXECUTE IMMEDIATE 'ALTER INDEX CF11_DW_X01 REBUILD';
LOG_MSG('P_CF11_DW_LOAD', '경고: ' || SQLERRM);
END;
[일요일 — 스케줄러와 로그 테이블]
USER_SCHEDULER_JOB_RUN_DETAILS P_CF11_DW_LOAD · STATUS SUCCEEDED · 01:10:02 ~ 01:10:09
로그 테이블
01:10:03 P_CF11_DW_LOAD 경고: ORA-01502: index 'PUP.CF11_DW_PK' or partition of such index is in unusable state
[월요일 09:05]
SELECT COUNT(*) FROM CF11_DW; → 0
USER_INDEXES CF11_DW_PK VALID · CF11_DW_X01 VALID (빈 테이블에 다시 지었다)
[연습 DB · 같은 순서를 손으로 다시 돌림]
ALTER INDEX CF11_DW_X01 UNUSABLE 만 하고 PK 는 켠 채 두면 같은 INSERT 가 된다
→ 적재 6.1 초 · redo 131 MB (대부분 PK 를 적재 끝에 한꺼번에 고치는 몫) · X01 REBUILD 1.6 초
두 인덱스를 다 끄면
→ ORA-01502 (위와 같다)