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

교환용 테이블을 똑같이 떴는데 EXCHANGE가 ORA-14097로 거부된다

기초DDL한빛유통416 / 700

상황 ​

한빛유통 정산팀은 주문 테이블에서 효과를 본 교환 방식을 정산 파티션 테이블 T_ORD_STLM_P에도 쓰기로 했다. 7월 정산부터 교환용 테이블을 채워 미리 만들어 둔 빈 7월 칸과 맞바꾼다. 교환용 테이블은 SELECT * … WHERE 1 = 0으로 껍데기만 떴고, DESC 결과도 두 테이블이 똑같다. 그런데 교환 문장이 ORA-14097로 거부된다. 조민우: "컬럼 이름도 타입도 크기도 다 같은데요."

테이블과 인덱스 ​

  • T_ORD_STLM_P 정산(파티션 복사본, 문제 설정): T_ORD_STLM 100,000행 · 640블록을 PARTITION BY RANGE (STLM_DT) 월별 24칸(P202301 ~ P202412)과 빈 PMAX로 나눴다. 칸 하나는 약 4,170행이다. 7월 칸 P202407은 미리 만들어 둔 빈 칸이다.
  • 보이는 컬럼은 STLM_SEQ NUMBER(10) · ORD_SEQ NUMBER(10) · CUS_ID VARCHAR2(40) · STLM_DT DATE · STLM_AMT NUMBER(12)이다.
  • 2023년 3월, 쓰지 않게 된 비고 컬럼 STLM_MEMO VARCHAR2(200)을 업무 시간에 지우려고 ALTER TABLE T_ORD_STLM_P SET UNUSED (STLM_MEMO)를 돌렸다(소스 주석).
  • LOCAL 유니크 인덱스 UX_STLM_P (ORD_SEQ, STLM_DT). 제약과 GLOBAL 인덱스는 없다.
  • T_ORD: 100,000행 · PAY_DT는 결제일(시분초 없음)이다. 2024년 7월 결제는 4,212건이다.

원본 SQL ​

sql
-- 7월 정산을 교환으로 넣는다
CREATE TABLE T_STLM_X202407 AS
SELECT * FROM T_ORD_STLM_P WHERE 1 = 0;

INSERT /*+ APPEND */ INTO T_STLM_X202407 (STLM_SEQ, ORD_SEQ, CUS_ID, STLM_DT, STLM_AMT)
SELECT SQ_STLM.NEXTVAL, o.ORD_SEQ, o.CUS_ID, o.PAY_DT, o.PAY_AMT
  FROM T_ORD o
 WHERE o.PAY_DT >= DATE '2024-07-01'
   AND o.PAY_DT <  DATE '2024-08-01';
COMMIT;

CREATE UNIQUE INDEX UX_STLM_X202407 ON T_STLM_X202407 (ORD_SEQ, STLM_DT);

ALTER TABLE T_ORD_STLM_P
  EXCHANGE PARTITION P202407 WITH TABLE T_STLM_X202407
  INCLUDING INDEXES WITH VALIDATION;

실행계획 학습용 예시 ​

xplan
[실행 결과]
  CREATE TABLE T_STLM_X202407 AS SELECT * ... WHERE 1 = 0       Table created.
  INSERT /*+ APPEND */ INTO T_STLM_X202407 ...                   4,212 rows created.
  CREATE UNIQUE INDEX UX_STLM_X202407 ...                        Index created.
  ALTER TABLE T_ORD_STLM_P EXCHANGE PARTITION P202407 ...
  ORA-14097: column type or size mismatch in ALTER TABLE EXCHANGE PARTITION

[DESC · 두 테이블이 같다]
  STLM_SEQ NUMBER(10) · ORD_SEQ NUMBER(10) · CUS_ID VARCHAR2(40) · STLM_DT DATE · STLM_AMT NUMBER(12)

[USER_TAB_COLS · 숨은 컬럼까지]
  TABLE_NAME       INTERNAL_COLUMN_ID  COLUMN_NAME                   HIDDEN_COLUMN  DATA_TYPE
  T_ORD_STLM_P     1 ~ 5               STLM_SEQ ~ STLM_AMT           NO
  T_ORD_STLM_P     6                   SYS_C00006_23031410:12:55$    YES            VARCHAR2(200)
  T_STLM_X202407   1 ~ 5               STLM_SEQ ~ STLM_AMT           NO

[USER_UNUSED_COL_TABS]
  TABLE_NAME       COUNT
  T_ORD_STLM_P     1

문제 ​

  1. DESC로는 같은 두 테이블을 오라클이 왜 다르다고 보는지 설명하시오.
  2. 교환이 되도록 교환용 테이블을 다시 만드는 SQL을 작성하고, T_ORD_STLM_P의 숨은 컬럼을 실제로 지우는 방법과 비교해 각각의 대가를 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자