不能直接对物化视图启用压缩,因其元数据与刷新机制强耦合,alter table ... compress 会报 ora-14302;可压缩其基表(如时间分区表)和物化视图日志(mlog$_表),但需注意行移动、pctfree 设置及统计信息更新。

不能直接对物化视图本身启用压缩,但可以对它的基表(尤其是按时间分区的基表)和物化视图日志(MLOG$_ 表)分别压缩。关键在于:物化视图只是查询结果的存储快照,Oracle 不允许对 MATERIALIZED VIEW 对象执行 COMPRESS;真正能压缩的是它背后依赖的物理段。
为什么不能直接 compress 物化视图?
Oracle 将物化视图(特别是 ON PREBUILT TABLE 方式创建的)视为普通表,但对其施加了额外限制:ALTER TABLE ... COMPRESS 会报 ORA-14302: unsupported operation on materialized view 或静默失败。根本原因在于 MV 的元数据与刷新机制耦合紧密,压缩可能破坏日志同步、ROWID 映射或快速刷新路径。即使你查 DBA_TABLES 发现其 SEGMENT_TYPE = 'TABLE',也不代表它支持标准表压缩语义。
对时间分区基表启用高级行压缩(OLTP)
若基表是按时间(如 CREATE_TIME)范围或间隔分区的,且已启用行移动(ENABLE ROW MOVEMENT),可对单个老分区启用压缩,避免全表锁和长停机:
ALTER TABLE sales_data MODIFY PARTITION p_2024_q1 ROW STORE COMPRESS ADVANCED;- 必须先确认该分区未被标记为
READ ONLY,否则报ORA-14502: partition is read only - 压缩不会影响正在运行的快速刷新——只要日志中
SNAPTIME$$水位线正常,增量变更仍可捕获 - 注意:压缩后
PCTFREE默认变为 0,若该分区仍有高频 DML,需手动设回,例如ALTER TABLE sales_data MODIFY PARTITION p_2024_q1 PCTFREE 10;
压缩物化视图日志(MLOG$_xxx)表
MLOG$_sales_data 是普通堆表,可安全压缩,且能显著减少日志膨胀带来的空间压力:
- 先启用行移动:
ALTER TABLE MLOG$_sales_data ENABLE ROW MOVEMENT; - 再执行压缩:
ALTER TABLE MLOG$_sales_data ROW STORE COMPRESS BASIC;(基础压缩即可,因日志写入密集、读取稀疏) - 验证是否生效:
SELECT compression, compress_for FROM dba_tables WHERE table_name = 'MLOG$_SALES_DATA'; - ⚠️ 切勿对日志表用
ADVANCED压缩:OLTP 压缩在高并发 INSERT 场景下可能引入额外 CPU 开销,而日志表的核心诉求是写入吞吐和空间效率
压缩后刷新行为是否受影响?
不影响。只要满足以下三点,DBMS_MVIEW.REFRESH(..., 'F') 仍走 FAST 路径:
- 物化视图定义未含
SYSDATE、分析函数嵌套、外连接等禁用 FAST 的语法 - 基表主键/唯一约束完整,且日志建时用了
INCLUDING NEW VALUES - 压缩操作未触发基表统计信息失效——建议压缩后立即
DBMS_STATS.GATHER_TABLE_STATS,否则优化器可能误判分区剪枝效果
真正容易被忽略的是:压缩不自动重写已有数据块。对已存在大量旧数据的分区,ROW STORE COMPRESS ADVANCED 只对后续 INSERT/UPDATE 生效;要压缩存量数据,必须配合 ALTER TABLE ... MOVE PARTITION 或数据泵重建——而这会中断刷新链,需提前将 SNAPTIME$$ 手动置为安全值并暂停应用写入。











