shrink space不会使索引失效,而alter table move会因ROWID变更导致索引失效;shrink space仅收缩表段,shrink space cascade则额外收缩相关索引段但不重建、不改变ROWID。

shrink space 为什么会让索引失效?
它不会。这是最常见的误解——ALTER TABLE ... SHRINK SPACE 默认不使索引失效,前提是没加 MOVE,且表是堆表、启用了行移动(ENABLE ROW MOVEMENT)。
真正导致索引失效的操作是 ALTER TABLE ... MOVE,因为该操作会物理重写所有行,每行的 ROWID 全部改变;而普通 B-Tree 索引的叶节点里存的就是 ROWID,一旦批量变更,索引就无法正确定位数据,Oracle 自动将其置为 UNUSABLE 状态。
shrink space cascade 和 shrink space 的区别在哪?
SHRINK SPACE 只作用于表段本身,不碰索引;SHRINK SPACE CASCADE 会顺带对所有相关索引执行 SHRINK SPACE(注意:不是 REBUILD),这一步也**不会让索引失效**,只是收缩索引段、调整其 HWM。
容易混淆的点:
-
SHRINK SPACE CASCADE≠MOVE + REBUILD INDEX - 它不改索引结构,也不重排索引键,只清理索引段内部碎片、释放空闲块
- 索引仍可用,查询、DML 都不受影响
- 但若索引本身已处于
UNUSABLE状态,SHRINK会报错,必须先REBUILD
哪些操作真会导致索引失效?
除了 MOVE,还有这些常见场景:
-
ALTER TABLE ... SPLIT PARTITION(分区拆分)——局部索引可能失效 -
ALTER INDEX ... DROP COLUMN(虽极少用,但会破坏索引结构) -
ALTER TABLE ... DROP PRIMARY KEY CASCADE—— 关联的唯一索引会被删掉 - 手动执行
ALTER INDEX ... UNUSABLE - LOB 列上做
MOVE时,隐式重建 LOBINDEX,旧索引失效
收缩后查不到索引状态?
别只看 DBA_INDEXES.STATUS,它只反映是否 VALID/UNUSABLE;更关键的是确认索引段是否被实际收缩过:
- 查
DBA_SEGMENTS.BYTES对比收缩前后变化 - 执行
ANALYZE INDEX ... VALIDATE STRUCTURE看INDEX_STATS中的DEL_LF_ROWS是否下降 - 注意:
SHRINK SPACE不更新NUM_ROWS,需手动DBMS_STATS.GATHER_INDEX_STATS
最常被忽略的一点:即使收缩成功,如果表上有基于 ROWID 的触发器(比如审计类),必须在 SHRINK 前 DISABLE,否则会报错中断;而 MOVE 则根本不管这个,直接失败。











