Skip to content
튜닝 연습파티션
PART-046

이관 리허설에서 월별 적재 작업 넷을 동시에 띄웠는데 한 번에 하나씩만 돈다

중급INSERT한빛유통421 / 700

상황 ​

한빛유통은 주말 작업 창에 옛 서버의 T_ORD_BIG을 새 서버의 월별 파티션 T_ORD_BIG_P14로 옮긴다. 이관 스크립트는 36개월을 달마다 작업 하나로 나눠 스케줄러에 올리고, DB 링크로 받는 시간이 길어서 넷씩 동시에 돌게 했다. 작업마다 직접 경로로 넣는다. EE 시험 DB 리허설에서 작업 하나는 약 3초였는데, 36개를 다 넣는 데 1분 52초가 걸렸다. 넷씩 돌면 30초 안팎이어야 한다. 그 시간 대기 1위는 enq: TM - contention이었다.

테이블과 인덱스 ​

  • T_ORD_BIG@OLD 원본(옛 서버, DB 링크): 1,000,000행 · 5,826블록 · 이관 중에는 아무도 고치지 않는다. 한 달은 약 27,800행이다(2024년 6월 27,390행).
  • T_ORD_BIG_P14 대상(새 서버, 교재 14화 설계): PARTITION BY RANGE (ORD_DT) 월별 36칸(P202201 ~ P202412)과 빈 PMAX. 빈 테이블로 먼저 만들었고 STORAGE (INITIAL 64K)를 주었다. 인덱스는 적재가 끝난 뒤 만든다. 이관 중에는 다른 세션이 이 테이블을 쓰지 않는다.
  • 새 서버는 EE이고 CPU는 8개, 병렬 실행이 켜져 있다. 옛 서버와의 링크는 세션 하나에 초당 약 1만 행을 받는다.

원본 SQL ​

sql
-- 이관 작업 하나 (스케줄러가 :m 을 2022-01-01 ~ 2024-12-01 로 바꿔 36번 띄운다 · 동시에 4개)
INSERT /*+ APPEND */ INTO T_ORD_BIG_P14 (ORD_SEQ, CUS_ID, ORD_DT, ORD_ST, ORD_AMT)
SELECT ORD_SEQ, CUS_ID, ORD_DT, ORD_ST, ORD_AMT
  FROM T_ORD_BIG@OLD
 WHERE ORD_DT >= :m
   AND ORD_DT <  ADD_MONTHS(:m, 1);
COMMIT;

실행계획 학습용 예시 · EE 시험 DB 기준 ​

xplan
[작업 하나 · :m = 2024-06-01 (단독 실행)]
---------------------------------------------------------------------------------------------------
| Id  | Operation                        | Name          | Starts | E-Rows | A-Rows |      A-Time | Buffers |
---------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT                 |               |      1 |        |      0 | 00:00:03.02 |     251 |
|   1 |  LOAD AS SELECT                  | T_ORD_BIG_P14 |      1 |        |      0 | 00:00:03.02 |     251 |
|   2 |   OPTIMIZER STATISTICS GATHERING |               |      1 |  27778 |  27390 | 00:00:02.95 |       0 |
|   3 |    REMOTE                        | T_ORD_BIG     |      1 |  27778 |  27390 | 00:00:02.91 |       0 |
---------------------------------------------------------------------------------------------------

Remote SQL Information (identified by operation id):
----------------------------------------------------
   3 - SELECT "ORD_SEQ","CUS_ID","ORD_DT","ORD_ST","ORD_AMT" FROM "T_ORD_BIG" "T_ORD_BIG"
       WHERE "ORD_DT">=:1 AND "ORD_DT"<ADD_MONTHS(:1,1) (accessing 'OLD')

[스케줄러 기록 · 리허설]
  슬롯 4 · 작업 36 · 전체 1분 52초 · 작업마다 실제로 넣는 시간 약 3초, 나머지는 대기

[V$SESSION · V$LOCK 표본 · 01:00:10]
  SID   EVENT                   OBJECT          LMODE  REQUEST  BLOCKING_SESSION
  141   (적재 중)                T_ORD_BIG_P14   6      0
  142   enq: TM - contention    T_ORD_BIG_P14   0      6        141
  143   enq: TM - contention    T_ORD_BIG_P14   0      6        141
  144   enq: TM - contention    T_ORD_BIG_P14   0      6        141

문제 ​

  1. 작업 넷이 한 번에 하나씩만 돈 까닭을 실행계획과 잠금 표본으로 설명하시오.
  2. 작업 넷이 서로 기다리지 않도록 이관 작업의 SQL을 고치고, 고친 SQL이 지켜야 할 조건을 쓰시오.
  3. 36개 작업 대신 한 문장의 병렬 DML로 옮기는 안과 비교해, 이 이관에 어느 쪽을 권할지 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자