Oracle 19c中归档分区无法直接压缩,因行压缩是段级属性,需通过MOVE PARTITION COMPRESS FOR OLTP等物理重构实现,或新建时指定压缩表空间。

归档分区本身不能被“压缩”,Oracle 19c 没有 ALTER PARTITION COMPRESS 这类语法;真正可行的是对归档数据所在的表或分区启用行压缩(ROW STORE COMPRESS),或迁移至压缩表空间,但必须在数据写入前完成配置。
为什么直接对已有归档分区执行 COMPRESS 会失败
常见错误现象是执行 ALTER TABLE t MODIFY PARTITION p202301 COMPRESS FOR OLTP 报 ORA-14658:不支持对已存在分区单独启用压缩。这是因为 Oracle 的行压缩策略(COMPRESS FOR OLTP、BASIC 等)是段级(segment-level)属性,不是分区级动态开关——它在段创建时由 CREATE TABLE 或 MOVE PARTITION 时决定,后续无法仅对某个分区“打补丁”开启。
- 已存在的分区若建表时未指定压缩,其数据块格式就是非压缩的,RDBMS 不提供在线重写所有块的原生能力
-
ALTER TABLE ... COMPRESS只影响后续 INSERT/UPDATE 的新数据,不会重组历史数据块 - 试图用
MOVE PARTITION ... COMPRESS是唯一路径,但它需要额外空间、会锁分区、且不适用于只读归档场景(如启用了READ ONLY表空间)
对历史归档分区实际有效的压缩路径
必须通过物理重构来实现:把老分区的数据导出 → 创建带压缩的新分区 → 导入 → 切换。核心是绕过“原地压缩”幻想,接受一次性的 MOVE 成本。
- 确认目标分区是否可移动:检查是否在
READ ONLY表空间中,若是,先临时设为READ WRITE(ALTER TABLESPACE ts_arch READ WRITE) - 执行带压缩的分区移动:
ALTER TABLE t MOVE PARTITION p202301 COMPRESS FOR OLTP ONLINE(19c 支持ONLINE,减少业务阻塞) - 移动后立即重建本地索引:
ALTER INDEX idx_t_local REBUILD PARTITION p202301,否则索引失效 - 如果表有全局索引,移动分区会导致全局索引失效,需加
UPDATE GLOBAL INDEXES子句,或事后ALTER INDEX ... REBUILD - MOVE 后务必收集统计信息:
DBMS_STATS.GATHER_TABLE_STATS,否则优化器仍按旧压缩率估算
更轻量的替代方案:压缩表空间 + 新建归档分区
如果历史分区数量多、MOVE 成本过高,推荐改用“压缩就绪”的归档流程:不再压缩旧数据,而是确保新归档分区从创建起就压缩。这比抢救旧数据更可持续。
- 创建专用压缩表空间:
CREATE TABLESPACE ts_arch_comp DATAFILE '/u01/oradata/arch_comp.dbf' SIZE 10G DEFAULT COMPRESS FOR OLTP - 后续新建归档分区时显式指定该表空间:
ALTER TABLE t ADD PARTITION p202410 VALUES LESS THAN (DATE '2024-11-01') TABLESPACE ts_arch_comp - 已有非压缩分区无法“迁入”该表空间并自动压缩——
MOVE PARTITION ... TABLESPACE ts_arch_comp仍需加COMPRESS才生效,否则只是换个地方存非压缩数据 - 注意:
DEFAULT COMPRESS仅对新创建的段生效,不影响已存在段
验证压缩是否真实生效的关键点
别只看 DBA_SEGMENTS.bytes,它反映分配空间而非实际压缩后占用。真正要看的是数据块内部密度。
- 查压缩后块使用率:
SELECT segment_name, compression, compress_for FROM dba_tab_partitions WHERE partition_name = 'P202301'—— 确认compress_for是OLTP或BASIC - 对比移动前后逻辑读:
SELECT blocks, num_rows FROM dba_tab_partitions WHERE partition_name = 'P202301'—— 若blocks显著下降(比如从 50000 降到 32000),说明压缩有效 - 运行
ANALYZE TABLE t PARTITION(p202301) VALIDATE STRUCTURE CASCADE后查INDEX_STATS,观察HEIGHT和LF_BLKS是否减少(对索引压缩也适用) - 最易忽略的一点:如果分区含
LOB列,MOVE PARTITION不会压缩 LOB 段,需单独执行ALTER TABLE ... MODIFY LOB (...) (SHRINK SPACE)(仅 SECUREFILE 支持)


















