跳转到主内容
极星编程网:以代码为星,赴技术山海!

如何移动表到另一个表空间_ALTER TABLE MOVE操作与索引失效处理

ALTER TABLE MOVE 后所有索引均失效,因ROWID变更导致状态变为UNUSABLE,需手动重建;LOB段和统计信息也须单独处理,否则引发查询异常或性能问题。 ALTER TABLE MOVE 后索引全失效,不是 bug 是设计 oracle 的
alter table move
会重建表段,物理位置彻底改变,所有基于原行地址(rowid)的索引自动失效,状态变成
unusable
。这不是意外,是 oracle 对“移动即重写”的明确承诺——索引不跟着搬,因为 rowid 已作废。 唯一索引、主键索引、普通 B-Tree 索引,无一幸免 函数索引、位图索引同样失效,且重建时需确保函数依赖对象仍可用 如果表上有物化视图日志,
MOVE
会失败,必须先
DROP
再重建 执行前查
SELECT index_name, status FROM user_indexes WHERE table_name = 'YOUR_TABLE';
,心里有数 MOVE 表空间前必须手动重建索引,不能靠 ONLINE 或 AUTOMATIC Oracle 不提供自动修复索引的语法;
ALTER TABLE ... MOVE TABLESPACE xxx
完事之后,索引不会自己活过来。必须显式重建——要么用
ALTER INDEX ... REBUILD
,要么带
UPDATE GLOBAL INDEXES
(仅限分区表 + 全局索引场景)。 非分区表:逐个执行
ALTER INDEX idx_name REBUILD TABLESPACE new_ts;
想一步到位?用脚本生成语句:
SELECT 'ALTER INDEX ' || index_name || ' REBUILD TABLESPACE users;' FROM user_indexes WHERE table_name = 'T1' AND status = 'UNUSABLE';
REBUILD ONLINE
可以减少锁,但要求表有主键或唯一约束,且期间 DML 可能被阻塞几秒 别信
UPDATE INDEXES
能用于普通 MOVE——那是
ALTER TABLE ... SPLIT PARTITION
才支持的选项 MOVE 操作本身不锁 DML,但重建索引会,得卡点安排
ALTER TABLE ... MOVE
默认需要
EXCLUSIVE
表锁,整个过程阻塞 INSERT/UPDATE/DELETE。除非加
ONLINE
(12cR2+),否则业务高峰期千万别碰。 12cR2 及以上:用
ALTER TABLE t MOVE TABLESPACE ts_new ONLINE;
,DML 可并发,但会生成大量 undo 和 redo,且要求表无 LONG 列、无嵌套表、无域索引 重建索引时,
REBUILD ONLINE
允许 DML,但索引在重建中处于
VALIDATING
状态,查询可能走全表扫描,性能抖动明显 MOVE 前检查表大小和索引数量:10GB 表 + 5 个大索引,重建可能耗时几分钟,得提前跟业务方对齐窗口 别忘了统计信息:MOVE 后
USER_TAB_STATISTICS
的
NUM_ROWS
会变,记得跑
DBMS_STATS.GATHER_TABLE_STATS
LOB 字段让 MOVE 更复杂,容易漏掉 LOBSEGMENT 和 LOBINDEX 带
CLOB
/
BLOB
的表,
MOVE
不只动表段,还得单独处理 LOB 段和 LOB 索引——它们默认留在原表空间,不随主表一起搬,且不报错,极易遗漏。 查 LOB 位置:
SELECT column_name, segment_name, tablespace_name FROM user_lobs WHERE table_name = 'T1';
MOVE LOB 段要额外写:
ALTER TABLE t MOVE LOB (clob_col) STORE AS (TABLESPACE ts_new);
LOB 索引也得指定新表空间,否则还在老地方:
ALTER TABLE t MOVE LOB (clob_col) STORE AS (TABLESPACE ts_new ENABLE STORAGE IN ROW);
如果 LOB 列设了
DISABLE STORAGE IN ROW
,MOVE 后可能触发 ORA-22922( nonexistent LOB value),说明 LOB 数据没同步过去 实际操作里,最常被跳过的不是索引重建,而是 LOB 段迁移和统计信息刷新——这两步不出错,但一出就是数据查不到或慢得离谱。

相关文章