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

판매상품도 월별 칸으로 옮기려는데 판매상품 테이블에는 날짜가 없다

실전DDL유통400 / 700

상황 ​

유통 본사는 지난달 판매 CF10을 월별 파티션 CF10_P로 옮겼다. 이번에는 판매상품 CF11을 같은 달 단위로 나눠, 보관 기간(24개월)이 지난 달을 두 테이블에서 함께 칸째 들어내려 한다. 지금은 CF11을 매달 DELETE로 지운다. 그런데 CF11에는 날짜 컬럼이 없다. 조민우가 아래 초안을 냈고, 시험 DB 리허설 결과가 아래에 있다. 박팀장: "초안 말고 다른 길도 같이 비교해서 가져와."

테이블과 인덱스 ​

  • CF11 판매상품: 1,096,708행 · 8,204블록 · SLE_NO VARCHAR2(15) · ITM_NO · SLE_QTY · SLE_UPRC · PK CF11_PK (SLE_NO, ITM_NO)(높이 3). 한 달 약 45,700행, 영수증 하나에 상품 약 2.2개다.
  • CF10_P 판매: CF10 500,000행을 PARTITION BY RANGE (SLE_DT) 월별 24칸(P202201 ~ P202312)과 빈 PMAX로 나눴다. 칸 하나 FULL ≈ 191블록, P202306(18번째 칸)은 20,953행이다. PK CF10_P_PK (SLE_NO, SLE_DT) LOCAL. 판매번호는 판매일자 8자리 + - + 일련번호 4자리('20230615-0042')이고, CHECK SUBSTR(SLE_NO, 1, 8) = SLE_DT가 걸려 있다.
  • 조회 둘: ① 매장 POS 「영수증 상세」 WHERE SLE_NO = :sle_no (하루 약 3,000번) ② 본사 「월 상품 매출」 CF10_P와 판매상품을 한 달로 조인(하루 몇 번)
  • 운영은 ARCHIVELOG다. 다른 테이블이 CF11을 FK로 참조하지 않는다.

원본 SQL ​

sql
-- 초안 (조민우) : 판매상품에 판매일자를 붙이고 같은 키로 나눈다
ALTER TABLE CF11 ADD (SLE_DT VARCHAR2(8));

UPDATE CF11 d
   SET d.SLE_DT = (SELECT h.SLE_DT FROM CF10_P h WHERE h.SLE_NO = d.SLE_NO);
COMMIT;

CREATE TABLE CF11_P
PARTITION BY RANGE (SLE_DT)
( PARTITION P202201 VALUES LESS THAN ('20220201')
  -- … P202312 까지 월별
, PARTITION PMAX VALUES LESS THAN (MAXVALUE) )
AS SELECT * FROM CF11;

ALTER TABLE CF11_P ADD CONSTRAINT CF11_P_PK
  PRIMARY KEY (SLE_NO, ITM_NO, SLE_DT) USING INDEX LOCAL;

실행계획 학습용 예시 · UPDATE 리허설 수치는 어림값 ​

xplan
[리허설 ① · 판매일자를 채우는 UPDATE (시험 DB)]
------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                            | Name      | Starts | E-Rows | A-Rows |      A-Time | Buffers | Pstart | Pstop |
------------------------------------------------------------------------------------------------------------------------------
|   0 | UPDATE STATEMENT                     |           |      1 |        |      0 | 00:06:12.40 |     27M |        |       |
|   1 |  UPDATE                              | CF11      |      1 |        |      0 | 00:06:12.40 |     27M |        |       |
|   2 |   TABLE ACCESS FULL                  | CF11      |      1 |  1096K |  1096K | 00:00:00.41 |    8204 |        |       |
|   3 |   PARTITION RANGE ALL                |           |   500K |      1 |   500K | 00:01:51.20 |   24.5M |      1 |    25 |
|   4 |    TABLE ACCESS BY LOCAL INDEX ROWID | CF10_P    |    12M |      1 |   500K | 00:01:48.90 |   24.5M |      1 |    25 |
|*  5 |     INDEX RANGE SCAN                 | CF10_P_PK |    12M |      1 |   500K | 00:01:30.10 |     24M |      1 |    25 |
------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   5 - access("H"."SLE_NO"=:B1)

  redo 약 260MB · 행 이주(migrated rows) 약 31만 행 · 그동안 CF11 전체에 행 잠금

[리허설 ② · 초안 CF11_P에서 영수증 상세 (WHERE SLE_NO = :sle_no)]
-----------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name      | Starts | E-Rows | A-Rows |      A-Time | Buffers | Pstart | Pstop |
-----------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |           |      1 |        |      2 | 00:00:00.01 |      50 |        |       |
|   1 |  PARTITION RANGE ALL                |           |      1 |      2 |      2 | 00:00:00.01 |      50 |      1 |    25 |
|   2 |   TABLE ACCESS BY LOCAL INDEX ROWID | CF11_P    |     24 |      2 |      2 | 00:00:00.01 |      50 |      1 |    25 |
|*  3 |    INDEX RANGE SCAN                 | CF11_P_PK |     24 |      2 |      2 | 00:00:00.01 |      48 |      1 |    25 |
-----------------------------------------------------------------------------------------------------------------------------

   3 - access("SLE_NO"=:SLE_NO)

  (지금 CF11 에서는 CF11_PK 로 5블록)

문제 ​

  1. 초안의 비용과 위험을 셋(판매일자를 채우는 UPDATE, PK의 뜻, 영수증 상세 조회)으로 나눠 위 숫자로 설명하시오.
  2. 날짜 컬럼을 붙이지 않고 CF11을 월별로 나누는 설계를 DDL로 작성하고, 영수증 상세와 월 상품 매출이 각각 몇 칸을 여는지 쓰시오.
  3. 초안, 위 설계, GLOBAL PK를 두는 안을 월 정리 비용과 부작용으로 비교하고, 고른 안을 지키려면 무엇을 확인해야 하는지 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자