DELETE后HWM不下降是正常设计,因Oracle仅标记数据为可重用;shrink space需先enable row movement,且不带compact才降HWM;move重建表可重置HWM但索引全失效;deallocate unused仅释放HWM上方空间。

DELETE后HWM不下降,这是正常行为
Oracle的高水位线(HWM)只升不降,DELETE操作只是把数据标记为“可重用”,并不回收空间或移动HWM位置。全表扫描仍会遍历HWM以下所有块——哪怕99%的块是空的。这不是bug,而是Oracle段管理的设计逻辑:避免频繁调整块地址映射带来的开销。
分区表优先用 shrink space 按分区收缩
对分区表直接执行 alter table t_par shrink space 会锁整张表、耗时极长;更安全的做法是按分区收缩:
- 先开启行移动:
alter table t_par enable row movement; - 收缩单个分区:
alter table t_par modify partition p_01 shrink space; - 收缩后索引仍有效,但局部索引需单独检查是否失效(全局索引不受影响)
- 注意:
shrink space compact只整理碎片、不降低HWM;真正降HWM必须执行不带compact的shrink space
alter table ... move 适合无大并发写入的维护窗口
该命令物理重建表段,直接重置HWM,但代价明确:
- 执行期间表不可DML(DDL级锁),且原表上所有索引全部失效,必须后续重建:
alter index idx_name rebuild; - 若指定新表空间,如
move tablespace users_new,可顺便做存储归档 - 不支持含
LONG、LOB列的表直接MOVE(需用shrink或expdp) - 比
shrink更快,尤其在HWM下方空块占比极高时
别忽略 deallocate unused 的边界作用
alter table t_par deallocate unused 不动HWM,但它能释放HWM之上的“悬空区”(比如之前用append插入又删掉的部分)。这步常被跳过,但对后续shrink或move有实际帮助:
- 它不锁表,执行快,可在业务低峰随时运行
- 仅释放HWM上方未被任何extents占用的空间,对HWM下方无效
- 建议在
shrink前先跑一遍,减少收缩时的无效扫描范围
真正难的不是选哪个命令,而是判断哪部分数据“永远不会再写入”。比如历史分区一旦归档完成,直接drop partition比任何收缩都干净;而活跃分区反复删写,shrink space compact加定期deallocate unused才是可持续方案。


















