oracle 19c中pct不支持按分区刷新api,局部快速刷新依赖fast逻辑自动跳过未变更分区日志,须同时满足单列range/list/interval分区、mv定义显式含分区键、建mv时启用enable query rewrite和pct、物化视图日志含with sequence及including new values四个硬性条件,缺一即静默降级为complete刷新。

Oracle 19c 中 PCT(Partition Change Tracking)本身不提供“按分区刷新”的 API,DBMS_MVIEW.REFRESH 也不接受 PARTITION 参数;所谓“局部快速刷新”,本质是让 FAST 刷新逻辑自动跳过未变更的分区日志,前提是满足全部硬性条件且日志扫描范围被有效约束。
必须同时满足的三个 PCT 硬性前提
缺一不可,否则 Oracle 会静默降级为 COMPLETE 刷新,且不报错:
- 基表是单列
RANGE、LIST或INTERVAL分区(如sale_date),不能是HASH或复合分区 - 物化视图定义中
SELECT和GROUP BY必须显式包含该分区键列——不能用别名、不能写TRUNC(sale_date)、不能隐式类型转换 - 建 MV 时必须带
ENABLE QUERY REWRITE和PCT属性(PCT不是可选项,是强制开关)
物化视图日志必须含 WITH SEQUENCE 和 INCLUDING NEW VALUES
19c 虽不强制语法报错,但漏掉任一都会导致 FAST 刷新不可靠:
-
WITH SEQUENCE缺失:同一行多次UPDATE后,日志只记最后一次变化,中间状态丢失 → 刷新结果错乱 -
INCLUDING NEW VALUES缺失:UPDATE的新值不进日志 → 刷新后该列仍为旧值或NULL - 日志列列表必须覆盖 MV
SELECT中所有列(含JOIN条件列、WHERE引用列),否则EXPLAIN_MVIEW会提示"cannot fast refresh"
验证是否真走 PCT 路径,别信 REFRESH_METHOD 字段
DBA_MVIEWS.REFRESH_METHOD = 'FAST' 只表示“支持 FAST”,不代表本次刷新真用了 PCT。必须实测验证:
- 运行
DBMS_MVIEW.EXPLAIN_MVIEW('MV_NAME'),查mv_capabilities_table表:possible = 'Y'且msgtxt不含"partition change tracking not supported" - 执行一次
REFRESH后,查V$SEGMENT_STATISTICS中基表各分区的logical reads—— 若只刷了 P202608,那只有该分区读数明显上升 - 19c 新增字段
DBA_MVIEW_ANALYSIS.PCT_REFRESHABLE,直接查它比翻EXPLAIN_MVIEW更快
手动缩小日志扫描面:靠 ROWID + SNAPTIME$$ 谓词
即使开了 PCT,大分区批量更新后 MLOG$_TABLE 日志仍可能堆积百万行,全扫触发磁盘排序。这时需主动限流:
- 先查目标分区物理范围:
SELECT partition_name FROM user_tab_partitions WHERE table_name = 'SALES' AND high_value LIKE '%2026-08%' - 构造日志过滤谓词:
WHERE mview_log_rowid IN (SELECT ROWID FROM SALES PARTITION (P202608)) -
SNAPTIME$$时间戳必须对齐——上次刷新时间是2026-08-25 14:30:00,本次就得从这个时间之后取日志,否则漏数据 - 这不是传参给
DBMS_MVIEW.REFRESH,而是改写自定义刷新过程中的日志查询逻辑
真正容易被忽略的是:PCT 刷新只在基表无聚合、无 JOIN 的简单场景下才稳定生效;一旦 MV 定义里有 SUM、COUNT(*) 或多表关联,Oracle 就可能绕过 PCT 路径,转而依赖完整日志扫描——这点在 19c 诊断输出里虽更明确,但逻辑没变。











