테마
본사 레거시 유통의 월 마감에 「매장 상품 월 판매 집계」를 새로 만들었다. 매장마다 상품의 판매 금액 순위도 함께 저장한다. 연습 DB(23ai Free)에서 몇 번 돌려 봤을 때는 문제가 없었는데, 12월 1일 운영(19c)에서 처음 돌리자 두 번째 문장에서 ORA-12838로 멈추고 전부 롤백됐다. 배치 담당자: "첫 문장이 끝났으니 그 테이블을 고치는 건 당연히 되는 줄 알았어요."
CF10 판매: 500,000행 · 4,583블록 · 2023년 11월 20,712건 · IX_CF10_SLE_DT (SLE_DT)CF11 판매상품: 1,096,708행 · 8,204블록 · CF11_PK (SLE_NO, ITM_NO) · 11월분 45,370행CF11_SHP_MON 매장 상품 월 집계(문제 설정): SLE_YM · SHP_NO · ITM_NO · SLE_QTY · SLE_AMT · AMT_RNK · PK (SLE_YM, SHP_NO, ITM_NO). 매장 다섯 곳에 한 달 약 530행이다. 이 배치만 쓴다.PROCEDURE P_SHP_ITM_MON(p_ym VARCHAR2) IS -- p_ym = '202311'
BEGIN
-- ① 매장 · 상품별 합계
INSERT /*+ APPEND */ INTO CF11_SHP_MON (SLE_YM, SHP_NO, ITM_NO, SLE_QTY, SLE_AMT)
SELECT p_ym, h.SHP_NO, d.ITM_NO, SUM(d.SLE_QTY), SUM(d.SLE_QTY * d.SLE_UPRC)
FROM CF10 h, CF11 d
WHERE d.SLE_NO = h.SLE_NO
AND h.SLE_DT BETWEEN p_ym || '01' AND p_ym || '31'
GROUP BY h.SHP_NO, d.ITM_NO;
-- ② 매장 안 판매 금액 순위
UPDATE CF11_SHP_MON m
SET AMT_RNK = (SELECT COUNT(*) + 1
FROM CF11_SHP_MON x
WHERE x.SLE_YM = m.SLE_YM
AND x.SHP_NO = m.SHP_NO
AND x.SLE_AMT > m.SLE_AMT)
WHERE m.SLE_YM = p_ym;
COMMIT;
EXCEPTION
WHEN OTHERS THEN ROLLBACK; RAISE;
END;
[운영 19c · 12/01 02:10 배치 로그]
① INSERT /*+ APPEND */ … 531 rows · 0.21 초 (LOAD AS SELECT)
② UPDATE CF11_SHP_MON …
ORA-12838: cannot read/modify an object after modifying it in parallel
ORA-06512: at "PUP.P_SHP_ITM_MON", line 12
→ ROLLBACK · CF11_SHP_MON 11월분 0행
[연습 DB 23ai Free · 같은 프로시저 · 같은 데이터]
① 531 rows · ② 531 rows updated · COMMIT · 정상 종료
[① 실행계획 — 운영]
----------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
----------------------------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 1 | | 0 |00:00:00.21 | 8462 |
| 1 | LOAD AS SELECT | CF11_SHP_MON | 1 | | 0 |00:00:00.21 | 8462 |
| 2 | HASH GROUP BY | | 1 | 535 | 531 |00:00:00.20 | 8401 |
|* 3 | HASH JOIN | | 1 | 45614 | 45370 |00:00:00.18 | 8401 |
| 4 | TABLE ACCESS BY INDEX ROWID BATCHED| CF10 | 1 | 20850 | 20712 |00:00:00.01 | 248 |
|* 5 | INDEX RANGE SCAN | IX_CF10_SLE_DT | 1 | 20850 | 20712 |00:00:00.01 | 59 |
| 6 | TABLE ACCESS FULL | CF11 | 1 | 1096K| 1096K|00:00:00.09 | 8153 |
----------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("D"."SLE_NO"="H"."SLE_NO")
5 - access("H"."SLE_DT">=:B1||'01' AND "H"."SLE_DT"<=:B1||'31')