必须显式在SELECT中引用各基表ROWID别名(如t1.ROWID t1_rid),且每张基表日志须含WITH ROWID与对应SEQUENCE;否则快速刷新静默降级为COMPLETE。
oracle 11g 物化视图完全支持包含 rowid 的快速刷新——问题不在“不支持”,而在于 rowid 是快速刷新的强制要求,不是可选项。如果你发现带 rowid 的物化视图仍无法快速刷新,那一定是它没被正确使用或配套条件缺失。
ROWID 别名(如 t1.ROWID t1_rid)来关联日志里的变更记录。 它不会自动推导、也不会从 JOIN 条件或 WHERE 中提取隐含的 ROWID。 - 错误写法:SELECT id, name FROM t1 JOIN t2 ON ... → 缺 ROWID,REFRESH_FAST_POSSIBLE = 'N' - 正确写法:SELECT t1.ROWID t1_rid, t2.ROWID t2_rid, t1.id, t2.name FROM t1 JOIN t2 ON ...别名必须唯一且带表前缀(如 t1_rid),否则 DBMS_MVIEW.EXPLAIN_MVIEW 会报 MSGNO = 2012:“missing rowid for base table”。
ROWID 出现在 SELECT 中只是表层要求;底层还必须为每张基表创建含 WITH ROWID 的物化视图日志: - CREATE MATERIALIZED VIEW LOG ON t1 WITH ROWID, SEQUENCE(id) INCLUDING NEW VALUES; - 不能只写 WITH PRIMARY KEY —— 即使 id 是主键,WITH PRIMARY KEY 也不保证日志含 ROWID 字段(尤其在 IOT 表或未启用 ROWID 支持时) - 检查日志是否生效:SELECT rowids FROM DBA_MVIEW_LOGS WHERE master = 'T1'; 返回必须是 'Y'如果日志中 rowids = 'N',哪怕 SELECT 写了十遍 t1.ROWID,刷新仍静默降级为 COMPLETE。
ROWID,需显式启用 INCLUDING ROWID(11g 有限支持,建议避免) - 多表 JOIN 中漏掉某一张表的 ROWID:哪怕只漏一个,整个 MV 就不可快速刷新 - ROWID 别名重复或非法(如含空格、纯数字):导致解析失败,EXPLAIN_MVIEW 可能报 MSGNO = 2003 或更模糊的语法错误 - 基表做了 ALTER TABLE ... MOVE 或 SHRINK SPACE:会重置 ROWID,旧日志失效,必须重建物化视图日志 最隐蔽的点:日志表 MLOG$_T1 的 STATUS 是 INVALID,或其 MASTER_OBJECT_ID 与基表 OBJECT_ID 不一致 —— 这种断裂不会报错,但 REFRESH_FAST 永远为 N。
DBMS_MVIEW.EXPLAIN_MVIEW('MV_NAME') 后查: - CAPABILITY_NAME = 'REFRESH_FAST' 对应的 POSSIBLE 必须是 'Y' - MSGTXT 里不能出现 “missing rowid”、“rowid not logged”、“log does not contain rowid” - 关键字段 REFRESH_FROM_LOG_AFTER_INSERT 应为 TRUE(而非 UNKNOWN 或 FALSE) 别只看语句能执行——11g 的快速刷新失败常常不抛错,只悄悄退化。真正可靠的信号,永远来自 EXPLAIN_MVIEW 输出和 DBA_MVIEW_LOGS 的状态一致性。