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

월요일 아침부터 정산 기간 조회가 91블록에서 5,822블록이 됐는데 에러는 하나도 없다

중급PLSQL한빛유통464 / 700

상황 ​

야간 체인 ① 재적재는 14화 이후 TRUNCATE → 인덱스 UNUSABLE → APPEND → REBUILD 순서로 돈다. 월요일 09:20, 조민우: "정산 기간 조회가 오늘 아침부터 느려요. 0.02초 걸리던 게 0.3초예요." 같은 시간 DB 서버 CPU는 평소의 두 배였다. 이 조회는 정산 화면에서 시간당 약 1,800번 호출된다. 체인 로그를 보니 REBUILD 단계 하나에 경고가 남아 있었다. 체인은 단계가 실패해도 경고로 적고 다음 단계로 넘어가게 되어 있다.

테이블과 인덱스 ​

  • T_ORD_BIG: 1,000,000행 · 5,826블록 · 2024년 6월 27,390행 · 낮에는 읽기만 한다.
  • 인덱스 IX_ORD_BIG_DT_AMT (ORD_DT, ORD_AMT)(Q1 정산 기간 조회, 리프 3,206블록) · IX_ORD_BIG_DT_SEQ (ORD_DT, ORD_SEQ)(Q4 정산 목록 페이징, 리프 3,344블록)
  • 정산팀의 월마감 집계(별도 스케줄, 일요일 22:00 ~ 22:30)가 같은 시각에 TEMP를 크게 쓴다. TEMP는 2GB다.
  • 인스턴스 파라미터 skip_unusable_indexes는 기본값 TRUE다.

원본 SQL ​

sql
-- 일요일 22:00 · 체인 ① (단계마다 따로 돈다 · 실패하면 경고를 적고 다음 단계로)
-- [1-1]
TRUNCATE TABLE T_ORD_BIG;
-- [1-2]
ALTER INDEX IX_ORD_BIG_DT_AMT UNUSABLE;
ALTER INDEX IX_ORD_BIG_DT_SEQ UNUSABLE;
-- [1-3]
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;
-- [1-4]
ALTER INDEX IX_ORD_BIG_DT_AMT REBUILD;
-- [1-5]
ALTER INDEX IX_ORD_BIG_DT_SEQ REBUILD;
-- [1-6]
EXEC DBMS_STATS.GATHER_TABLE_STATS(USER, 'T_ORD_BIG')

실행계획 학습용 예시 · 숫자는 교재 02화와 14화 규모 ​

xplan
[체인 로그 — 일요일]
  22:00:04  [1-1] TRUNCATE                       완료
  22:00:04  [1-2] UNUSABLE × 2                   완료
  22:00:05  [1-3] INSERT APPEND 1,000,000행       완료
  22:00:05  [1-4] REBUILD IX_ORD_BIG_DT_AMT       경고  ORA-01652: unable to extend temp segment by 128 in tablespace TEMP
  22:00:07  [1-5] REBUILD IX_ORD_BIG_DT_SEQ       완료
  22:00:08  [1-6] 통계 수집                       완료
  …  체인 종료 03:41 · 상태 「경고 1」

[월요일 09:25 · USER_INDEXES]
  INDEX_NAME           STATUS     LEAF_BLOCKS
  IX_ORD_BIG_DT_AMT    UNUSABLE
  IX_ORD_BIG_DT_SEQ    VALID      3344

[월요일 09:25 · Q1 정산 기간 조회]
SELECT SUM(ORD_AMT) FROM T_ORD_BIG WHERE ORD_DT >= :B1 AND ORD_DT < :B2     -- 2024-06-01 ~ 2024-07-01
-------------------------------------------------------------------------------------------
| Id  | Operation          | Name      | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |           |      1 |        |      1 |00:00:00.29 |    5822 |
|   1 |  SORT AGGREGATE    |           |      1 |      1 |      1 |00:00:00.29 |    5822 |
|*  2 |   TABLE ACCESS FULL| T_ORD_BIG |      1 |  27390 |  27390 |00:00:00.28 |    5822 |
-------------------------------------------------------------------------------------------
   2 - filter(("ORD_DT">=:B1 AND "ORD_DT"<:B2))

  (지난 금요일 같은 SQL: INDEX RANGE SCAN IX_ORD_BIG_DT_AMT · Buffers 91)

문제 ​

  1. Q1이 에러 없이 FULL로 바뀐 이유를 위 로그와 딕셔너리로 설명하고, CPU가 두 배가 된 것을 숫자로 설명하시오.
  2. 지금 바로 할 조치와, 같은 사고가 다시 나지 않도록 체인 ①을 고치는 방법을 SQL로 작성하시오.
  3. REBUILD가 실패한 원인에 대한 대책을 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자