物化视图本身不支持分区,但可通过on prebuilt table方式基于已分区的底层表实现分区独立维护,前提是表结构匹配、创建物化视图日志并满足fast刷新条件。

只读物化视图本身不能分区,但底层存储表可以手动分区
Oracle 的物化视图对象(MATERIALIZED VIEW)不支持直接指定 PARTITION BY 子句。所谓“分区独立维护”,实际是指:让物化视图所依赖的物理存储表具备分区结构,从而在后续刷新、查询、清理等操作中获得分区剪枝、DROP PARTITION 快速裁剪等能力。
关键前提是:该物化视图必须使用 ON PREBUILT TABLE 创建方式——即提前建好一张已分区的普通表,再将其“注册”为物化视图。否则默认创建的物化视图底层是不可见的堆表,无法分区。
- 必须先用
CREATE TABLE ... PARTITION BY RANGE/LIST/HASH建好目标结构表,并确保列名、类型、约束与物化视图查询完全一致 - 该表需显式创建本地索引(
LOCAL)或全局索引(注意 12c+ 支持异步维护) -
CREATE MATERIALIZED VIEW ... ON PREBUILT TABLE语句不会修改表结构,仅绑定刷新逻辑 - 若跳过
ON PREBUILT TABLE直接用BUILD IMMEDIATE,则无法事后分区——DDL 会报ORA-14006: invalid partition name
FAST刷新依赖物化视图日志,且必须含主键 + ROWID + SELECT列
只读物化视图要支持 REFRESH FAST,基表(源分区表)必须有配套的物化视图日志,且日志内容必须覆盖物化视图定义中所有被引用的列。常见错误 ORA-12052: cannot fast refresh materialized view 多半源于日志缺失或字段不全。
- 基表必须有主键(
PRIMARY KEY)或启用RELY ENABLED的唯一约束;无主键则强制退化为COMPLETE刷新 - 执行
CREATE MATERIALIZED VIEW LOG ON your_source_table WITH PRIMARY KEY, ROWID, SEQUENCE(col1,col2) INCLUDING NEW VALUES——col1,col2是物化视图SELECT中实际用到的列,不能省略 - 即使基表是
INTERVAL分区,日志也只需建在主表名上,无需为每个分区单独操作 - 避免在物化视图定义中出现
SYSDATE、子查询、聚合函数或DISTINCT,否则无法 FAST 刷新
分区独立维护的核心操作:TRUNCATE/DROP PARTITION + 异步索引维护
当物化视图底层表已分区,且你按时间范围(如 LOG_DATE)做了范围分区,就可以对过期分区执行 TRUNCATE PARTITION 或 DROP PARTITION,而不影响其他分区数据和查询可用性。12c+ 的关键优势在于:全局索引可保持可用。
- 执行
ALTER TABLE mv_target TRUNCATE PARTITION p_2024_q1 UPDATE GLOBAL INDEXES后,全局索引不会失效,但维护动作被异步延迟 - 真正索引修复由后台作业
SYS.PMO_DEFERRED_GIDX_MAINT_JOB(默认每天 02:00)触发,也可手动运行DBMS_SCHEDULER.RUN_JOB('SYS.PMO_DEFERRED_GIDX_MAINT_JOB') - 若需立即生效,改用
ALTER INDEX idx_name REBUILD,但会短暂阻塞 DML - 注意:该异步机制仅适用于堆表,不支持 IOT、
SYS用户对象或物化视图自身(即不能对物化视图对象执行TRUNCATE PARTITION)
刷新时绕过全量锁表:atomic_refresh=FALSE + 并行 INSERT
对 TB 级分区物化视图,首次填充或滚动窗口刷新若用默认 REFRESH COMPLETE,极易因长时间锁表导致业务阻塞。正确做法是关闭原子性,改用并行直插替代全量重建。
- 调用
DBMS_MVIEW.REFRESH('mv_target', 'C', atomic_refresh => FALSE),此时 Oracle 会先清空表(TRUNCATE),再执行INSERT /*+ APPEND PARALLEL(8) */,避免生成大量 undo 和 redo - 必须确保物化视图底层表已禁用外键、触发器等可能干扰直插的机制
- 若底层表是分区表,
TRUNCATE阶段仍会按分区粒度清理,配合UPDATE GLOBAL INDEXES可保障索引持续可用 - 该方式不适用于
FAST刷新场景,仅用于周期性重刷历史快照类物化视图
SELECT 投影严格一致,差一个字段就退化;还有人误以为给物化视图对象加分区语法可行,其实那只是语法报错前的徒劳尝试。











