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

14화 처방대로 바꾼 주문상품 일 적재가 0.6초에서 41초로 늘었다

중급INSERT버거462 / 700

상황 ​

버거원 본사는 매일 03:00에 전날 POS 주문상품을 ORD_ITEM에 더한다. 하루 약 3,400행이다. 지난달 신입 개발자가 교재 14화의 처방(인덱스를 끄고 직접 경로로 넣은 뒤 다시 짓는다)을 이 단계에 그대로 옮겼다. PK는 유니크라서 끌 수 없다는 것까지 알고 ORD_ITEM_X01만 끈다. 그 뒤로 적재 단계가 0.6초에서 41초로 늘었고, 아카이브 로그는 하루 70MB 넘게 늘었다. 03:02에 도는 본사 재고 연동 조회도 가끔 2초씩 걸린다.

테이블과 인덱스 ​

  • ORD_ITEM 주문상품: 2,472,717행 · 55,265블록 · 날짜순 적재 · 하루 약 3,400행(테이블의 0.14%)
  • 인덱스 ORD_ITEM_PK (ORD_NO, ITEM_ID): 리프 약 8,900블록 · ORD_ITEM_X01 (ORD_DT, ORD_HMS): 리프 약 9,500블록
  • STG_ORD_ITEM 수신 테이블: 날마다 비우고 POS 파일을 받는다(약 3,400행 · 80블록).
  • 03:02에 본사 재고 연동이 전날 주문상품을 ORD_DT로 읽는다(평소 ORD_ITEM_X01 · 약 120블록).
  • 운영은 ARCHIVELOG이고 테이블과 인덱스는 LOGGING이다. 03:00 ~ 03:02에 이 테이블에 쓰는 다른 세션은 없다.

원본 SQL ​

sql
-- 매일 03:00 · 전날 주문상품 적재 (지난달 수정본)
ALTER INDEX ORD_ITEM_X01 UNUSABLE;

INSERT /*+ APPEND */ INTO ORD_ITEM (ORD_NO, ITEM_ID, ORD_ITEM_QTY, ORD_DT, ORD_HMS)
SELECT ORD_NO, ITEM_ID, ORD_ITEM_QTY, ORD_DT, ORD_HMS
  FROM STG_ORD_ITEM;
COMMIT;

ALTER INDEX ORD_ITEM_X01 REBUILD;

실행계획 학습용 예시 ​

xplan
[적재 단계 — 바꾸기 전과 뒤 (운영 · 사흘 평균)]
                                    바꾸기 전                      바꾼 뒤
  넣는 법                           일반 INSERT · 인덱스 켠 채      X01 끄고 → APPEND → REBUILD
  INSERT 3,412행                    0.6 초 · redo 2.7 MB           0.1 초 · redo 1.6 MB
  ALTER INDEX ORD_ITEM_X01 REBUILD  —                              40.8 초 · redo 74.3 MB
  합계                              0.6 초 · redo 2.7 MB           40.9 초 · redo 75.9 MB

[REBUILD 한 번의 일 — 세션 통계]
  physical reads (ORD_ITEM 전체 스캔)    55,265 블록
  sorts (rows)                          2,476,129
  Used-Tmp                              약 62 MB
  새로 쓴 인덱스 블록                    약 9,500

[03:02 재고 연동 조회 — REBUILD가 끝나기 전에 돈 날]
---------------------------------------------------------------------------------------
| Id  | Operation          | Name     | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |          |      1 |        |   3412 |00:00:01.92 |   55270 |
|*  1 |  TABLE ACCESS FULL | ORD_ITEM |      1 |   3400 |   3412 |00:00:01.92 |   55270 |
---------------------------------------------------------------------------------------
   1 - filter("ORD_DT"=:B1)
  (평소: INDEX RANGE SCAN ORD_ITEM_X01 · Buffers 약 120)

문제 ​

  1. 바꾼 뒤의 41초와 redo 75.9MB가 어디서 나오는지 REBUILD가 하는 일로 설명하시오.
  2. 이 적재를 고치고, 인덱스를 끄고 다시 짓는 방법이 맞는 적재와 맞지 않는 적재를 가르는 기준을 쓰시오.
  3. 바꾼 뒤 03:02 재고 연동 조회가 가끔 느렸던 이유를 설명하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자