테마
본사 레거시 유통은 운영 판매 보관 기간을 2년에서 18개월로 줄이기로 했다. 처음 한 번은 2022년 1 ~ 6월을 지우고, 그 뒤로는 매달 가장 오래된 한 달을 지운다. 24시간 매장 두 곳의 POS가 새벽에도 판매를 넣으므로 테이블을 새로 만들어 바꿔 끼울 수는 없고, 언두 여유가 작아서 한 번에 지우지 말라는 DBA의 요청이 있었다. 개발자가 5,000건씩 지우고 커밋하는 루프를 짰다. 리허설에서 판매상품 루프만 1분 48초가 걸렸는데, DBA가 회차별 기록을 보더니 물었다. "5,000건 지우는 데 매번 블록을 4,600 ~ 6,600개씩 읽고, 뒤로 갈수록 더 읽네요?"
CF10 판매: 500,000행 · 4,583블록(블록당 약 109행) · 판매 날짜순 적재 · 2022-01-01 ~ 2023-12-31 · CF10_PK (SLE_NO) · IX_CF10_SLE_DT (SLE_DT) · 2022년 1 ~ 6월 124,318건CF11 판매상품: 1,096,708행 · 8,204블록(블록당 약 134행) · CF11_PK (SLE_NO, ITM_NO) · 판매번호 순으로 쌓였다 · 2022년 1 ~ 6월 272,200행SLE_NO VARCHAR2(15): 판매일자 8자리 + - + 그날의 일련번호 4자리('20220103-0127'). CF11과 CF10 사이에 FK는 없다.T_JOB_LOG (JOB_NM, PIECE, ROWS_DONE, DONE_AT) 작업 기록 테이블이 있다. 통계는 최신이다.-- 보관 기간 단축 · 처음 한 번 2022년 1 ~ 6월 (개발팀)
DECLARE
v_cnt NUMBER;
BEGIN
LOOP -- ① 판매상품
DELETE FROM CF11
WHERE SLE_NO IN (SELECT SLE_NO FROM CF10 WHERE SLE_DT < '20220701')
AND ROWNUM <= 5000;
v_cnt := SQL%ROWCOUNT;
COMMIT;
EXIT WHEN v_cnt = 0;
END LOOP;
LOOP -- ② 판매
DELETE FROM CF10
WHERE SLE_DT < '20220701'
AND ROWNUM <= 5000;
v_cnt := SQL%ROWCOUNT;
COMMIT;
EXIT WHEN v_cnt = 0;
END LOOP;
END;
[① 판매상품 루프 — 54회차 DELETE (DISPLAY_CURSOR · ALLSTATS LAST)]
-------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
-------------------------------------------------------------------------------------------
| 0 | DELETE STATEMENT | | 1 | | 0 |00:00:02.08 | 21730 |
| 1 | DELETE | CF11 | 1 | | 0 |00:00:02.08 | 21730 |
|* 2 | COUNT STOPKEY | | 1 | | 5000 |00:00:00.41 | 6582 |
|* 3 | HASH JOIN RIGHT SEMI| | 1 | 5000 | 5000 |00:00:00.41 | 6582 |
|* 4 | TABLE ACCESS FULL | CF10 | 1 | 124K| 124K|00:00:00.09 | 4583 |
| 5 | TABLE ACCESS FULL | CF11 | 1 | 1096K| 5000 |00:00:00.03 | 1999 |
-------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(ROWNUM<=5000)
3 - access("SLE_NO"="SLE_NO")
4 - filter("SLE_DT"<'20220701')
[회차별 기록 — ① 판매상품]
회차 지운 행 행을 찾는 데 읽은 블록 경과
1 5,000 4,621 1.6초
2 5,000 4,658 1.6초
27 5,000 5,583 1.8초
54 5,000 6,582 2.1초
55 2,200 6,620 1.4초
56 0 6,620 0.9초 (0행임을 알려고 한 번 더 다 읽는다)
합계 272,200 약 316,000 1분 48초 · user commits 56
[② 판매 루프] 25회차 · 행을 찾는 데 읽은 블록 약 15,000 · 3초
[세션 통계 — ①과 ② 합계] redo size 약 96 MB · undo change vector size 약 41 MB