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