高级行压缩需显式启用且依赖advanced compression许可;alter table compress for oltp仅修改元数据,不压缩现有数据;真正压缩须用move操作,但需排他锁、等量空闲空间并手动重建索引。

高级行压缩(Advanced Row Compression)在 Oracle 12c 中能显著降低表段空间,但必须显式启用且依赖许可;不查 V$OPTION 就执行 COMPRESS FOR OLTP,大概率白忙一场。
为什么 ALTER TABLE COMPRESS FOR OLTP 不会缩小现有数据段
该语句只改元数据标记,不重写物理块。执行后 DBA_TAB_PARTITIONS.COMPRESS_FOR 可能显示 ADVANCED,但 DBA_SEGMENTS.BYTES 完全不变——老数据仍按原始格式躺在数据块里,空闲空间没回收,块内也没压缩。
- 新插入/更新的行才会走压缩逻辑(需配合
ENABLE ROW MOVEMENT) - 对已存在百万级数据的表,光改表属性毫无空间收益
- 误以为“设了就生效”,是 DBA 最常踩的压缩认知坑
真正压缩已有数据必须用 MOVE + COMPRESS FOR OLTP
ALTER TABLE ... MOVE COMPRESS FOR OLTP 是最直接路径,但它不是“在线”操作:MOVE 过程中表会被加 EXCLUSIVE 锁,DML 全部阻塞。
- 需要等量空闲空间:MOVE 先建新压缩段,再删旧段,
DBA_SEGMENTS.BYTES值就是最低可用空间要求 - 索引不会自动重建:
ALTER INDEX ... REBUILD必须手动补上,否则查询可能报ORA-01502 - 若表无主键或唯一约束,MOVE 后全局索引可能失效,需检查
DBA_INDEXES.STATUS
验证压缩是否真实落地的三个硬指标
别信元数据,盯住这三个值:
-
DBA_SEGMENTS.BYTES:同一表移动前后对比,下降幅度要达 MB 级(例如 84 MB → 52 MB),才算压缩见效 -
DBA_TABLES.COMPRESSION必须为ENABLED,且DBA_TABLES.COMPRESS_FOR显示OLTP或ADVANCED(不是BASIC) -
V$SEGSTAT中该段的logical reads若明显上升(+10%~20%),说明压缩块被读取,CPU 解压开销已发生
Advanced Compression 许可未启用时的静默降级行为
没开许可,COMPRESS FOR OLTP 语句看似成功,实际退化为 BASIC 压缩——只在 direct-path insert 时生效,普通 DML 和已有数据完全不压缩。
- 必须运行:
SELECT VALUE FROM V$OPTION WHERE PARAMETER = 'Advanced Compression';,返回TRUE才可靠 - 如果返回
FALSE,所有COMPRESS FOR子句都无效,连MOVE都不会产生压缩效果 - 许可状态不可动态开启,需联系 Oracle 销售并重启实例
最容易被忽略的是许可验证和空间预估:MOVE 前不查 V$OPTION 和 DBA_SEGMENTS.BYTES,等于在黑盒里做高风险操作。











