compress for oltp在分区表上仅对后续dml生效,压缩已有数据须执行alter table ... move partition ... compress for oltp等物理重写操作,且需启用row movement、重建索引并验证效果。
对分区表启用 compress for oltp 是可行的,但必须明确:它只对后续新插入或更新的数据生效,不会自动压缩已有数据。
COMPRESS FOR OLTP 在分区表上实际生效的条件
Oracle 12c 中 COMPRESS FOR OLTP(等价于 ROW STORE COMPRESS ADVANCED)在分区表上不是“一键全量压缩”,而是按分区、按操作逐步生效。关键点包括:
-
ALTER TABLE ... COMPRESS FOR OLTP只影响后续 DML(如INSERT、UPDATE),不重写历史数据块 - 若想压缩已有数据,必须触发物理重写——最常用的是
ALTER TABLE ... MOVE PARTITION ... COMPRESS FOR OLTP - 在线移动(
ONLINE)支持,但会短暂持有TX锁,且要求表有主键或唯一约束(否则索引维护可能失败) - 分区级压缩属性可独立设置,例如一个表中
P1启用压缩、P2不启用,通过DBA_TAB_PARTITIONS.COMPRESS_FOR查看
如何安全地为已有分区启用 OLTP 压缩
直接对大分区执行 MOVE 风险高,建议分步操作:
- 先确认目标分区无长事务、无未提交 DML:
SELECT * FROM V$TRANSACTION WHERE ADDR IN (SELECT TADDR FROM V$SESSION WHERE SID IN (SELECT SID FROM V$SESSION WHERE EVENT LIKE '%enq: TX%')); - 启用行迁移(必要前提):
ALTER TABLE t1 ENABLE ROW MOVEMENT; - 执行在线压缩移动:
ALTER TABLE t1 MOVE PARTITION p2 ROW STORE COMPRESS ADVANCED ONLINE; - 移动后重建局部索引(如存在):
ALTER INDEX idx_t1_local REBUILD PARTITION p2;;全局索引默认自动维护,但建议检查DBA_INDEXES.STATUS - 验证压缩效果:
SELECT PARTITION_NAME, COMPRESS_FOR, BYTES/1024/1024 MB FROM DBA_SEGMENTS WHERE SEGMENT_NAME = 'T1' AND PARTITION_NAME = 'P2';
COMPRESS FOR OLTP 和 COMPRESS BASIC 的关键区别
别名混乱是常见坑点,12c 中语义已收敛,但兼容旧写法导致误判:
-
COMPRESS BASIC(即 11g 的COMPRESS)仅对直接路径插入(INSERT /*+ APPEND */)有效,普通 DML 不压缩 -
COMPRESS FOR OLTP/ROW STORE COMPRESS ADVANCED对所有 DML 类型都有效,包括常规INSERT、UPDATE、DELETE - 两者 CPU 开销接近,但
ADVANCED在高并发小事务场景下更稳定,BASIC更适合批量 ETL 场景 -
COMPRESS FOR QUERY LOW/HIGH属于列式压缩(HCC),仅限 Exadata,普通环境执行会报错ORA-64307: hybrid columnar compression is not supported for this storage type
容易被忽略的副作用和限制
压缩不是“开箱即用”的优化开关,几个硬性约束常被跳过检查:
- 压缩分区无法再设为
READ ONLY—— 执行ALTER TABLE t1 MODIFY PARTITION p2 READ ONLY会报ORA-14466: Data in a read-only partition cannot be modified,但压缩本身不阻止该操作;真正冲突的是:一旦分区设为READ ONLY,就无法再执行MOVE压缩 -
PCTFREE值会被隐式调高(通常到 10),防止频繁迁移;若原分区PCTFREE设为 0,移动后会强制重设,可能影响后续密集更新性能 - 物化视图日志表、IOT 表、含
LONG列的表不支持MOVE ... COMPRESS - 如果表上有函数索引(
CREATE INDEX ... ON t1(UPPER(col))),MOVE后需手动REBUILD,否则查询可能走全表扫描
真正起效的压缩依赖数据重写动作,不是改个 DDL 就能立竿见影;尤其对已运行多年的 OLTP 分区表,务必先在非高峰时段对单个分区做完整验证——包括空间变化、DML 延迟、索引一致性,再推广到全表。











