Skip to content
튜닝 연습DML과 배치 튜닝
DML-038

일요일 분석용 사본 재적재는 성공으로 끝났는데 월요일 아침 0건이다

중급PLSQL유통463 / 700

상황 ​

본사 레거시 유통은 매주 일요일 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와 트리거는 없다.
  • 지난주까지는 인덱스를 켠 채 일반 INSERT로 6분 12초가 걸렸다. MD팀 화면은 월요일 08:30 이후에만 쓴다.
  • skip_unusable_indexes는 기본값 TRUE다. LOG_MSG는 로그 테이블에 한 줄을 남기는 자율 트랜잭션 프로시저다.

원본 SQL ​

sql
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;

실행계획 학습용 예시 ​

xplan
[일요일 — 스케줄러와 로그 테이블]
  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 (위와 같다)

문제 ​

  1. INSERT가 ORA-01502로 실패한 이유와, 그런데도 배치가 성공으로 끝나 월요일까지 아무도 몰랐던 이유를 설명하시오.
  2. 기본 키를 지키면서 인덱스 유지 비용 없이 다시 채우도록 프로시저를 고치시오.
  3. 고친 방법에서 실패할 수 있는 지점과 그때 어떻게 알게 되는지 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자