物化视图参与查询重写必须同时满足四条件:QUERY_REWRITE_ENABLED参数开启、定义含ENABLE QUERY REWRITE子句、结构兼容(如UNION ALL需平铺、列类型一致)、基表有RELY约束且QUERY_REWRITE_INTEGRITY匹配。
物化视图要真正参与查询重写,不是建完就自动生效——必须同时满足参数、定义、结构、权限四方面硬性条件,缺一不可。
Oracle 默认关闭查询重写,哪怕物化视图带 ENABLE QUERY REWRITE,只要这个开关是 FALSE,优化器连候选列表都不会生成。
ALTER SYSTEM SET QUERY_REWRITE_ENABLED = TRUE;
ALTER SESSION SET QUERY_REWRITE_ENABLED = TRUE;
SELECT VALUE FROM V$PARAMETER WHERE NAME = 'query_rewrite_enabled'; —— 注意返回的是字符串 'TRUE' 或 'FALSE',不是数字ALTER SESSION,导致生产环境实际仍是默认 FALSE
建 MV 时漏掉 ENABLE QUERY REWRITE,它就只是个普通表,不会进入重写决策流程;/*+ REWRITE */ hint 也救不回来。
CREATE MATERIALIZED VIEW mv_sales REFRESH FAST ON COMMIT ENABLE QUERY REWRITE AS SELECT ...;
CREATE MATERIALIZED VIEW mv_sales REFRESH COMPLETE ON DEMAND AS SELECT ...;(缺子句 + 刷新方式也不支持重写)ALTER 补,只能 DROP 后重建ENABLE QUERY REWRITE 要求基表有主键或已启用 ROWID,否则建 MV 会报 ORA-30353
含 UNION ALL 的视图本身不会被重写器识别——优化器要求“单源语义可推导”,而 UNION ALL 是多源并集,无法安全映射刷新日志与键约束。
CREATE MATERIALIZED VIEW mv_hist_curr ENABLE QUERY REWRITE AS SELECT * FROM v_hist_union_all;(v_hist_union_all 是含 UNION ALL 的视图)CREATE MATERIALIZED VIEW mv_hist_curr ENABLE QUERY REWRITE AS SELECT col1, col2 FROM t_hist UNION ALL SELECT col1, col2 FROM t_curr;(逻辑平铺进 MV 定义)*;对应列数据类型要完全一致(如都为 VARCHAR2(50));NULL 性不一致时需用 CAST(... AS ...) 或 TO_NUMBER(NULL) 统一声明t_hist 中是 NOT NULL、在 t_curr 中是 NULL,MV 中该列最终为 NULL,应用层需接受此语义该参数控制优化器对物化视图数据新鲜度和约束可信度的要求,默认 ENFORCED 最严格,也是最容易静默失败的点。
ENFORCED:要求基表有 RELY ENABLE NOVALIDATE PRIMARY KEY 等约束,且 MV 必须是 FRESH 状态,否则直接跳过重写TRUSTED:允许基表约束为 NOVALIDATE,但必须标 RELY;MV 可以是 FRESH 或 STALE(取决于刷新策略)STALE_TOLERATED:即使 MV 是 STALE 状态也允许重写(风险自担)EXPLAIN PLAN FOR ... 后查 PLAN_TABLE_OUTPUT,看 OBJECT_NAME 是否为 MV 名;也可用 DBMS_MVIEW.EXPLAIN_REWRITE 查具体失败原因最常被忽略的是 QUERY_REWRITE_INTEGRITY 和基表约束的配合——尤其在迁移或新建环境时,RELY 约束容易遗漏,导致明明 MV 状态正常、参数全开,却始终不重写。