EXCHANGE PARTITION能秒级导入导出数据,因其仅交换元数据而非移动实际数据文件;要求源表与目标分区结构完全一致,包括列定义、约束、索引等,否则直接报错。
EXCHANGE PARTITION 为什么能“秒级”导入导出数据
因为
不移动实际数据文件,只交换元数据(比如分区定义、段名、高水位等),本质是把两个表的物理存储“换个名字”。只要源表和目标分区结构完全一致(列名、顺序、类型、not null 约束、索引、约束等),就能跳过 insert/load 的逐行写入开销。
但这也意味着:一旦结构有细微差异,语句直接报错,不会静默兼容。
源表必须和目标分区所属表具有完全相同的列定义(包括隐式类型转换不被允许)
源表不能有主键或唯一索引(除非目标表也启用
,且索引结构匹配)
源表不能有外键引用,也不能被外键引用(否则需先禁用约束)
目标分区必须为空(
不会清空它,只做交换;若非空,需先
)
ORA-14097 错误:列顺序或类型不匹配的典型表现
执行
时抛出
,大概率不是类型“看起来不同”,而是细节没对齐。
常见真实原因:
列和
列互换 —— 即使都存时间,Oracle 视为不兼容
源表某列为
,目标分区对应列为
或
—— 单位不显式声明时默认行为可能不一致
一列在源表为
,另一列为
(无精度)—— Oracle 认为后者可容纳更大范围,但交换要求“完全一致”
源表含虚拟列,而目标分区表不含,或反之
查证方式:用
对比两者的
、
、
、
、
、
字段,一个都不能差。
如何安全地准备 staging 表(避免反复建表失败)
别手写
,容易漏掉约束或隐藏属性。最稳的方式是用目标表的 DDL 做基础,再删掉分区逻辑:
用
获取原表完整 DDL
手动删掉
及所有
子句
删掉
(非必需,但 staging 表通常不需要)
确保
、
、
等物理属性与目标分区所在表空间一致(否则交换后可能触发隐式移动)
特别注意:staging 表的
必须和目标分区当前所在的表空间相同,否则
会失败(ORA-14157)。如果不确定,先查
的
字段。
EXCHANGE 后数据“消失”?其实是分区归属变了
执行成功后发现数据“不见了”,不是丢了,而是原来在
里的数据,现在属于
的某个分区;而原来
分区里的数据,现在跑到了
表里。
所以正确流程应该是:
导入新数据到
(用
或
)
确认
数据无误,且目标分区为空
执行
此时
成了“空壳”,里面是原分区的老数据;真正的新数据已在
的
中
如需复用
,执行
清空老数据即可
最容易被忽略的是:交换后,
的统计信息不会自动更新,后续如果误用它做查询计划估算,可能严重失真。记得手动
。
exchange partitionINCLUDING INDEXESEXCHANGETRUNCATE PARTITIONALTER TABLE t EXCHANGE PARTITION p1 WITH TABLE t_stagingORA-14097: column type or size mismatch in ALTER TABLE EXCHANGE PARTITIONDATETIMESTAMPVARCHAR2(100)VARCHAR2(100 CHAR)VARCHAR2(100 BYTE)NUMBER(10,2)NUMBERDBA_TAB_COLUMNSDATA_TYPEDATA_LENGTHDATA_PRECISIONDATA_SCALECHAR_LENGTHNULLABLECREATE TABLEDBMS_METADATA.GET_DDL('TABLE', 'T')PARTITION BY ...PARTITIONENABLE ROW MOVEMENTCOMPRESSSEGMENT CREATIONTABLESPACETABLESPACEEXCHANGEDBA_TAB_PARTITIONSTABLESPACE_NAMEt_stagingttt_stagingt_stagingINSERT /*+ APPEND */SQL*Loader DIRECT=TRUEt_stagingALTER TABLE t EXCHANGE PARTITION p1 WITH TABLE t_stagingt_stagingtp1t_stagingTRUNCATE TABLE t_stagingt_stagingDBMS_STATS.GATHER_TABLE_STATS