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

정산 확정 MERGE에서 ORA-38104를 피하려고 조건을 뺐더니 확정된 정산까지 다시 고쳐진다

중급MERGE한빛유통453 / 700

상황 ​

정산 원장 T_ORD_STLM에는 확정 칸 STLM_ST가 있다('N' 미확정, 'Y' 확정). 매일 23:00 배치가 미확정 정산의 금액과 정산일을 주문의 결제 금액과 결제일로 채우고 확정한다. 처음 짠 MERGE는 ON 절에 s.STLM_ST = 'N'을 넣었다가 ORA-38104로 멈췄고, 개발자가 그 조건을 빼서 돌아가게 만들었다. 그 뒤로 배치는 매일 10만 건을 모두 고친다. 그리고 이번 달 재무팀 대사에서, 지난달에 확정한 정산 37건의 금액이 확정 뒤에 바뀐 것이 드러났다. 정산팀 조민우: "확정된 정산은 금액이 바뀌면 안 돼요. 확정 뒤 결제 정정은 보정 이력으로 따로 남기거든요."

테이블과 인덱스 ​

  • T_ORD_STLM(정산 원장): 100,000행 · 640블록 · 인덱스 없음 · ORD_SEQ로 T_ORD와 1:1 · 이 문제에서는 STLM_ST CHAR(1) 칸이 더 있다('Y' 98,760 · 'N' 1,240)
  • T_ORD: 100,000행 · 896블록 · PK_T_ORD (ORD_SEQ) · PAY_AMT, PAY_DT
  • 통계는 최신이다.

원본 SQL ​

sql
-- 처음 판:  ON (s.ORD_SEQ = o.ORD_SEQ AND s.STLM_ST = 'N')
--   → ORA-38104: Columns referenced in the ON Clause cannot be updated: "S"."STLM_ST"
-- 지금 판 (ON 절에서 STLM_ST 조건을 뺐다)
MERGE INTO T_ORD_STLM s
USING T_ORD o
   ON (s.ORD_SEQ = o.ORD_SEQ)
 WHEN MATCHED THEN UPDATE
      SET s.STLM_AMT = o.PAY_AMT,
          s.STLM_DT  = o.PAY_DT,
          s.STLM_ST  = 'Y';

실행계획 학습용 예시 ​

xplan
[세션 통계 — 어제 23:00] 갱신된 행 100,000 (그중 미확정 1,240) · redo 약 27 MB · 확정 정산 가운데 금액이 바뀐 행 37

-------------------------------------------------------------------------------------------
| Id  | Operation             | Name       | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------------------------------
|   0 | MERGE STATEMENT       |            |      1 |        |      0 |00:00:01.21 |    103K |
|   1 |  MERGE                | T_ORD_STLM |      1 |        |      0 |00:00:01.21 |    103K |
|   2 |   VIEW                |            |      1 |        |    100K|00:00:00.08 |    1540 |
|*  3 |    HASH JOIN          |            |      1 |    100K|    100K|00:00:00.07 |    1540 |
|   4 |     TABLE ACCESS FULL | T_ORD_STLM |      1 |    100K|    100K|00:00:00.01 |     644 |
|   5 |     TABLE ACCESS FULL | T_ORD      |      1 |    100K|    100K|00:00:00.01 |     896 |
-------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   3 - access("S"."ORD_SEQ"="O"."ORD_SEQ")

문제 ​

  1. 처음 판이 ORA-38104로 멈춘 이유를 설명하시오.
  2. 지금 판이 무엇을 망가뜨렸는지 실행계획과 숫자로 설명하시오.
  3. 미확정 정산만 고치도록 다시 작성하고, 그 고침이 처음 판과 같은 뜻이 되는 조건을 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자