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

PARALLEL 8을 붙인 월간 스냅샷 적재가 3분 18초에서 줄지 않는다

실전INSERT버거468 / 700

상황 ​

매월 1일 01:00 본사 DW 이관 배치는 운영 ORD_ITEM 전체를 스냅샷 테이블 DW_ORD_ITEM_SNAP에 다시 담는다. 다음 단계(DW 전송)가 01:30에 시작하는데 이 단계가 3분 18초 걸려, 데이터가 늘면 겹칠 것이라는 걱정이 나왔다. 개발팀이 PARALLEL 8 힌트를 붙였지만 시간은 그대로였다. 운영은 EE이고 병렬 실행이 켜져 있다(parallel_max_servers 32). 01:00 ~ 01:30에 이 서버에서 도는 다른 배치는 매장 마감 집계 하나이고, 그 배치도 DOP 8로 돈다.

테이블과 인덱스 ​

  • ORD_ITEM: 2,472,717행 · 55,265블록(약 432MB) · 01:00 ~ 01:30에 이 테이블을 고치는 세션은 없다.
  • ITEM 상품: 92행 · 5블록
  • DW_ORD_ITEM_SNAP 스냅샷(문제 설정): ORD_ITEM 컬럼에 ITEM_NM과 ITEM_TYPE_CD를 붙인 사본 · 인덱스, 제약, 트리거 없음 · 매달 비우고 다시 채운다 · DW 전송 단계만 읽는다.
  • 운영 DB는 ARCHIVELOG이고 DW_ORD_ITEM_SNAP은 NOLOGGING이다(DW로 넘긴 뒤에는 다시 만들 수 있는 사본이라 승인받았다). FORCE LOGGING은 NO다.

원본 SQL ​

sql
-- 매월 1일 01:00 · DW 이관용 스냅샷
TRUNCATE TABLE DW_ORD_ITEM_SNAP;

INSERT /*+ APPEND PARALLEL(t 8) */ INTO DW_ORD_ITEM_SNAP t
       (ORD_NO, ITEM_ID, ITEM_NM, ITEM_TYPE_CD, ORD_ITEM_QTY, ORD_DT, ORD_HMS)
SELECT /*+ PARALLEL(i 8) */
       i.ORD_NO, i.ITEM_ID, m.ITEM_NM, m.ITEM_TYPE_CD, i.ORD_ITEM_QTY, i.ORD_DT, i.ORD_HMS
  FROM ORD_ITEM i, ITEM m
 WHERE m.ITEM_ID = i.ITEM_ID;
COMMIT;

SELECT COUNT(*) FROM DW_ORD_ITEM_SNAP;        -- 건수 확인 (DW 전송 단계에 넘긴다)

실행계획 학습용 예시 · 병렬 계획은 EE 모양(교재 14화 §9.3) ​

xplan
[실행계획 — 지금 (모양만)]
| Id | Operation                         | Name             |    TQ  | IN-OUT | PQ Distrib |
|  0 | INSERT STATEMENT                  |                  |        |        |            |
|  1 |  LOAD AS SELECT                   | DW_ORD_ITEM_SNAP |        |        |            |
|  2 |   OPTIMIZER STATISTICS GATHERING  |                  |        |        |            |
|  3 |    PX COORDINATOR                 |                  |        |        |            |
|  4 |     PX SEND QC (RANDOM)           | :TQ10001         |  Q1,01 | P->S   | QC (RAND)  |
|* 5 |      HASH JOIN                    |                  |  Q1,01 | PCWP   |            |
|  6 |       PX RECEIVE                  |                  |  Q1,01 | PCWP   |            |
|  7 |        PX SEND BROADCAST          | :TQ10000         |  Q1,00 | P->P   | BROADCAST  |
|  8 |         PX BLOCK ITERATOR         |                  |  Q1,00 | PCWC   |            |
|  9 |          TABLE ACCESS FULL        | ITEM             |  Q1,00 | PCWP   |            |
| 10 |       PX BLOCK ITERATOR           |                  |  Q1,01 | PCWC   |            |
| 11 |        TABLE ACCESS FULL          | ORD_ITEM         |  Q1,01 | PCWP   |            |

Predicate Information (identified by operation id):
---------------------------------------------------
   5 - access("M"."ITEM_ID"="I"."ITEM_ID")

Note
-----
   - Degree of Parallelism is 8 because of hint
   - PDML is disabled in current session

[세션 통계 · V$SESSION — 적재 한 번]
  경과                                   3분 18초
  queries parallelized                   1
  DML statements parallelized            0
  V$SESSION.PDML_STATUS                  DISABLED
  physical writes direct                 약 58,900 블록 (QC 한 세션이 썼다)
  redo size                              약 1.1 MB (NOLOGGING)

[V$PX_SESSION · ASH 표본 — 01:01:30]
  QC SID 88 · PX 서버 16개 (생산자 8 · 소비자 8)
  PX 서버 대기 1위  PX Deq Credit: send blkd (QC 가 받아 가기를 기다린다)

문제 ​

  1. 실행계획의 어느 줄을 보면 적재(LOAD AS SELECT)가 직렬로 처리되는지 알 수 있는지 줄 번호로 설명하고, PX 서버 16개가 무엇을 기다렸는지 쓰시오.
  2. 적재까지 병렬로 처리되도록 배치를 고치시오.
  3. 병렬 DML로 바꿀 때의 부작용과 이 배치에서 미리 확인할 것을 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자