ALTER TABLE … MOVE PARTITION 必须指定分区名,不可对整个分区表执行;需查 user_tab_partitions 确认分区,处理 LOB 和索引失效,注意锁、统计信息、压缩及 Oracle 12c+ ONLINE 限制。

ALTER TABLE … MOVE PARTITION 语法必须带分区名
直接对分区表执行 ALTER TABLE t1 MOVE TABLESPACE tbs2 会报错 ORA-14511,因为 Oracle 不允许对整个分区对象做表级 MOVE。必须明确指定要移动的分区(或子分区)。
常见错误是查了 dba_tables 就以为能套用普通表语法,结果执行失败。正确做法是查 dba_tab_partitions 或 user_tab_partitions:
SELECT table_name, partition_name, tablespace_name FROM user_tab_partitions WHERE table_name = 'YOUR_TABLE';- 确认目标分区当前是否已分配空间(
dba_segments中有记录),空分区(未插入过数据)MOVE 会报ORA-14257 - 语句末尾必须写全
TABLESPACE new_tbs,不能省略
LOB 字段和索引失效必须显式处理
MOVE PARTITION 只迁移表分区段,LOB 段和索引段完全不动 —— 这是生产环境最常漏掉的两处。
如果分区含 LOB 列,不加 LOB (col_name) STORE AS (TABLESPACE new_tbs),LOB 数据仍留在旧表空间,后续 UPDATE 可能因跨表空间引发性能问题或权限异常。
索引方面:
- 本地索引分区自动变为
UNUSABLE,查dba_ind_partitions的status字段可确认 - 全局索引默认失效;加
UPDATE GLOBAL INDEXES可避免,但会显著拖慢执行时间,且要求足够 TEMP 空间 - 重建单个本地索引分区:
ALTER INDEX idx_name REBUILD PARTITION p_2023q4 TABLESPACE new_tbs;
锁、统计信息和压缩需同步安排
MOVE PARTITION 是排他锁操作,整个分区在迁移期间不可读写。对 >10GB 的分区,持续时间可能达分钟级,不是“瞬间完成”。
迁移后常见性能骤降,往往不是数据搬错了,而是:
- 统计信息清空,优化器误判分区裁剪失效 → 必须立刻执行
DBMS_STATS.GATHER_TABLE_STATS(ownname => 'OWNER', tabname => 'TBL', granularity => 'PARTITION') - 新表空间使用归档存储(如
COMPRESS FOR ARCHIVE LOW),首次访问触发透明解压 → 需提前验证 I/O 延迟 - 未加
PARALLEL导致单线程迁移太慢 → 大分区建议加PARALLEL 8,但注意并行度受 CPU 和 TEMP 限制
Oracle 12c+ 支持 ONLINE,但有条件限制
12.1 起支持 ONLINE 移动分区,语法为:ALTER TABLE t1 MOVE PARTITION p_old TABLESPACE new_tbs ONLINE UPDATE INDEXES;
但它不等于“无锁”,只是将锁窗口缩到极短(仅最后元数据切换阶段)。实际仍需满足:
- 不能与
LOB、STORAGE、COMPRESS等其他子句混用 -
UPDATE INDEXES仅适用于全局索引;本地索引仍需手动重建 - 系统必须启用
ENABLE PLUGGABLE DATABASE(非 CDB 模式下不生效)
真正需要零停机的场景,DBMS_REDEFINITION 才是唯一可靠方案,但代价是双倍空间和更长执行时间 —— 冷热分层迁移通常没必要走这条路。


















