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

요일 칸 몇천 건을 바로잡는 보정 UPDATE가 매주 50만 건을 고친다

기초UPDATE유통444 / 700

상황 ​

본사 레거시 유통에서는 매주 월요일 새벽에 매장 POS 판매를 CF10으로 이관한다. 매장 두 곳의 POS가 요일 칸(SLE_DOW)을 비워 보내거나 틀리게 보내서, 이관이 끝나면 운영 담당이 요일 보정 SQL을 돌린다. 보정 한 번에 18초가 걸리고 redo가 약 118MB씩 생겨서, 월요일마다 아카이브 로그 공간 경보가 울린다. 운영 담당: "틀린 건 매주 3천 건 남짓인데, 로그는 왜 이렇게 많이 쌓이죠?"

테이블과 인덱스 ​

  • CF10 판매: 500,000행 · 4,583블록 · SLE_DT VARCHAR2(8) · SLE_DOW VARCHAR2(1)(일요일 '1' ~ 토요일 '7', NULL 허용)
  • 이번 주 이관 뒤 SLE_DOW가 NULL인 행 2,840건, 값이 틀린 행 312건. 나머지 496,848행은 이미 맞다.
  • 인덱스는 CF10_PK (SLE_NO)뿐이다. 트리거는 없다. DB는 ARCHIVELOG 모드다.
  • 보정 세션의 NLS 설정은 이관 프로그램과 같다('D' 형식이 일요일을 1로 낸다).

원본 SQL ​

sql
-- 매주 월요일 이관 뒤 · 요일 보정 (운영 담당)
UPDATE CF10
   SET SLE_DOW = TO_CHAR(TO_DATE(SLE_DT, 'YYYYMMDD'), 'D');
COMMIT;

실행계획 학습용 예시 ​

xplan
[세션 통계 — 보정 UPDATE 한 번]
  경과 시간                  18.4초
  갱신된 행                  500,000 (값이 실제로 바뀐 행 3,152)
  redo size                  약 118 MB
  undo change vector size    약 41 MB
  db block changes           약 1,010,000

-------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------------------------
|   0 | UPDATE STATEMENT   |      |      1 |        |      0 |00:00:18.40 |    517K |
|   1 |  UPDATE            | CF10 |      1 |        |      0 |00:00:18.40 |    517K |
|   2 |   TABLE ACCESS FULL| CF10 |      1 |    500K|    500K|00:00:00.21 |    4583 |
-------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   (없음 — WHERE 절이 없다)

문제 ​

  1. 값이 이미 맞는 496,848행에도 redo와 undo가 생기는 이유를 설명하시오.
  2. 결과가 바뀌지 않게, 값이 바뀌는 행만 고치도록 SQL을 고치시오. NULL인 행이 빠지지 않게 하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자