优先选WITH PRIMARY KEY,因基表无主键时用PRIMARY KEY会报ORA-12014;有主键时PRIMARY KEY日志更稳定、支持复杂查询且不受MOVE/分区操作影响,而ROWID日志易失效且限制多。

物化视图日志选 WITH ROWID 还是 WITH PRIMARY KEY?看基表有没有主键
没主键就别硬上 PRIMARY KEY 模式——Oracle 会直接报错 ORA-12014: table does not contain a primary key。这时候只能用 ROWID,但得清楚它带来的限制:ROWID 日志不支持包含 DISTINCT、GROUP BY、连接(JOIN)、子查询或聚合函数的物化视图定义;而 PRIMARY KEY 日志能支撑更复杂的查询结构,且是 REFRESH FAST 的前提条件之一。
REFRESH FAST 失败时,先查日志是否匹配物化视图类型
常见错误现象:ORA-12008: error in materialized view refresh path 或 ORA-12015: cannot create a fast refresh materialized view from a complex query。这不是 SQL 写错了,而是日志和物化视图声明不一致。比如:基表有主键,你建了 WITH ROWID 日志,但物化视图用了 REFRESH FAST WITH PRIMARY KEY,就会失败。必须保证三者对齐:
- 基表是否有主键 → 决定日志能否用
PRIMARY KEY - 日志建的时候用的
WITH子句 → 决定日志里存什么字段(M_ROW$$还是主键列) - 物化视图定义里的
REFRESH FAST选项 → 必须与日志类型兼容,不能混用
ROWID 日志在分区表或 ALTER TABLE MOVE 后会失效
ROWID 是物理地址,只要数据块位置变动,旧 ROWID 就作废。典型场景包括:
- 执行
ALTER TABLE ... MOVE整理碎片 - 分区表做
SPLIT/EXCHANGE操作 - 表启用压缩(
COMPRESS)后插入新数据
一旦发生,依赖该日志的 FAST 刷新会报 ORA-01410: invalid ROWID。而 PRIMARY KEY 日志不受影响——它靠主键值匹配变更行,逻辑稳定。所以哪怕基表有主键,也建议优先用 WITH PRIMARY KEY,除非业务明确要求只读堆表且严禁 DDL 变动。
物化视图日志里加 SEQUENCE 和列名,不是可有可无的装饰
如果物化视图查询里用了 MAX()、COUNT(*) 等聚合,或者需要按顺序应用变更(比如下游系统要求严格事务时序),就必须在日志中显式加上 SEQUENCE 和涉及的列:
-
SEQUENCE$$字段保证刷新时 DML 操作顺序不乱 - 只记录被查询引用的列(如
WITH (col_a, col_b)),能减少日志体积和 I/O 开销 - 漏掉关键列会导致
FAST刷新结果不一致,尤其是UPDATE后旧值/新值无法正确识别
最常被忽略的一点:即使基表有主键,如果你的物化视图 SQL 里 SELECT 了未包含在日志 WITH 列表中的字段,FAST 刷新也可能退化为 COMPLETE —— Oracle 不会报错,但 DBA_MVIEW_ANALYSIS 里能看到 FAST_REFRESHABLE 字段变成 NO。


















