Skip to content
튜닝 연습파티션
PART-038

보관 규정이 바뀐 뒤 칸째 들어내던 주문상태이력 정리가 다시 행마다 지우는 DELETE가 되었다

실전DDL한빛유통413 / 700

상황 ​

주문상태이력 T_ORD_LOG_P14는 월별 칸으로 나뉘어 있어서, 예전 규정(전부 24개월 보관)대로라면 매달 가장 오래된 칸을 DROP PARTITION 한 줄로 들어내면 됐다. 올해 1월 감사팀 규정이 바뀌었다. 결제(S)와 취소(X) 이력은 5년, 나머지 셋(접수 R, 배송 D, 완료 C)은 6개월만 보관한다. 조민우가 월 정리를 DELETE로 바꿨고, 첫 달에는 18개월 치 약 18만 행을 지웠다. 그 뒤로는 매달 1일 약 1만 행을 지운다. 오과장: "지운 칸이 가벼워지지도 않고, 5년 동안은 칸을 하나도 못 들어낸다. 설계를 다시 하자." 아래는 7월 1일의 월 정리다.

테이블과 인덱스 ​

  • T_ORD_LOG_P14 주문상태이력(교재 14화): 교재 05화의 T_ORD_LOG 500,000행(2023-01-01 ~ 2025-06-19, 900일, 3,602블록)을 PARTITION BY RANGE (LOG_DT) 월별 30칸과 PMAX로 나눠 CTAS로 지었다. 한 달은 약 17,000행, FULL로 약 120 ~ 124블록이다.
  • LOG_ST는 R · S · D · C · X 다섯 가지가 20%씩이다. 이력 행은 한 번 쓰면 고치지 않는다.
  • GLOBAL 인덱스 IX_LOG_P14_SEQ (ORD_SEQ): 「주문 이력」 화면용(주문 하나에 이력 약 5행, 하루 수천 번)
  • 그 밖의 SQL: 「월 상태 통계」 한 달 GROUP BY LOG_ST(월초 몇 번) · 「감사 추출」 분기마다 결제와 취소 이력(LOG_ST IN ('S', 'X'))
  • 운영은 ARCHIVELOG다. 23ai라서 UPDATE GLOBAL INDEXES는 지운 키를 고아 항목으로 남겼다가 나중에 정리한다.

원본 SQL ​

sql
-- 월 정리 (매월 1일 · :v_mon = 이번 달 첫날 · 7개월 전 달의 R · D · C 를 지운다)
DELETE FROM T_ORD_LOG_P14
 WHERE LOG_DT >= ADD_MONTHS(:v_mon, -7)
   AND LOG_DT <  ADD_MONTHS(:v_mon, -6)
   AND LOG_ST IN ('R', 'D', 'C');
COMMIT;

-- 「감사 추출」 (분기마다 · 2024년 4분기)
SELECT ORD_SEQ, LOG_DT, LOG_ST, LOG_MSG
  FROM T_ORD_LOG_P14
 WHERE LOG_ST IN ('S', 'X')
   AND LOG_DT >= DATE '2024-10-01'
   AND LOG_DT <  DATE '2025-01-01';

-- 「주문 이력」 (화면 · 하루 수천 번)
SELECT LOG_DT, LOG_ST, LOG_MSG FROM T_ORD_LOG_P14 WHERE ORD_SEQ = :ord_seq ORDER BY LOG_DT;

실행계획 학습용 예시 · 교재 05화 · 14화 규모 ​

xplan
[월 정리 · 2025-07-01 · 2024년 12월의 R · D · C]
-------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name          | Starts | E-Rows | A-Rows |      A-Time | Buffers | Pstart | Pstop |
-------------------------------------------------------------------------------------------------------------------------
|   0 | DELETE STATEMENT            |               |      1 |        |      0 | 00:00:00.34 |     31K |        |       |
|   1 |  DELETE                     | T_ORD_LOG_P14 |      1 |        |      0 | 00:00:00.34 |     31K |        |       |
|*  2 |   FILTER                    |               |      1 |        |  10333 | 00:00:00.02 |     124 |        |       |
|   3 |    PARTITION RANGE ITERATOR |               |      1 |  10320 |  10333 | 00:00:00.02 |     124 |    KEY |   KEY |
|*  4 |     TABLE ACCESS FULL       | T_ORD_LOG_P14 |      1 |  10320 |  10333 | 00:00:00.02 |     124 |    KEY |   KEY |
-------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter(ADD_MONTHS(:V_MON,-7)<ADD_MONTHS(:V_MON,-6))
   4 - filter((INTERNAL_FUNCTION("LOG_ST") AND "LOG_DT">=ADD_MONTHS(:V_MON,-7) AND "LOG_DT"<ADD_MONTHS(:V_MON,-6)))

[세션 통계 · 위 DELETE + COMMIT]
  지운 행 10,333 · 글로벌 인덱스 키 10,333개 삭제 · redo 약 2.9MB · undo 약 1.4MB

[그 뒤 · 2024년 12월 칸]
  남은 행 6,889 (S · X) · FULL Buffers 124 그대로 · 세그먼트 크기 그대로

[「감사 추출」 · 2024년 4분기]
-----------------------------------------------------------------------------------------------------------------------
| Id  | Operation                 | Name          | Starts | E-Rows | A-Rows |      A-Time | Buffers | Pstart | Pstop |
-----------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT          |               |      1 |        |  20444 | 00:00:00.03 |     368 |        |       |
|   1 |  PARTITION RANGE ITERATOR |               |      1 |  20444 |  20444 | 00:00:00.03 |     368 |     22 |    24 |
|*  2 |   TABLE ACCESS FULL       | T_ORD_LOG_P14 |      3 |  20444 |  20444 | 00:00:00.03 |     368 |     22 |    24 |
-----------------------------------------------------------------------------------------------------------------------

   2 - filter(("LOG_ST"='S' OR "LOG_ST"='X'))

[「주문 이력」]  TABLE ACCESS BY GLOBAL INDEX ROWID · INDEX RANGE SCAN IX_LOG_P14_SEQ · 8블록

문제 ​

  1. 보관 규정이 바뀐 뒤 칸째 들어낼 수 없게 된 까닭과, 지금 월 정리 DELETE의 비용을 위 숫자로 설명하시오.
  2. 두 보관 규칙을 모두 DDL 한 줄씩으로 지킬 수 있게 테이블을 다시 설계하고, 매달 정리와 5년 뒤 정리를 SQL로 쓰시오.
  3. 다른 설계 둘(상태로 먼저 나누고 그 안을 월로 나누기, 테이블을 둘로 나누기)과 비교하고, 고른 설계의 대가와 확인할 것을 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자