QUERY_REWRITE_ENABLED必须为TRUE,否则重写机制不启动;需同时满足全局参数开启、物化视图显式启用ENABLE QUERY REWRITE、语义等价、状态合法、统计完备、权限充足等条件,执行计划出现MATERIALIZED VIEW REWRITE才表明生效。

QUERY_REWRITE_ENABLED 必须为 TRUE,否则物化视图永远不会被重写——这不是可选开关,而是整个机制启动的前提。
为什么查询没走物化视图?先查这个参数
执行计划里看不到物化视图表名,V$SQL_PLAN 中 OBJECT_NAME 字段全是基表,说明重写根本没触发。最常见原因是会话级或系统级的 QUERY_REWRITE_ENABLED 被设为 FALSE。哪怕物化视图日志齐全、约束完整、数据新鲜,只要这个参数关着,优化器连看都不会看它一眼。
检查方式:
- 查当前会话:
SELECT name, value FROM v$parameter WHERE name = 'query_rewrite_enabled'; - 临时启用:
ALTER SESSION SET QUERY_REWRITE_ENABLED = TRUE; - 注意:
ALTER SYSTEM级设置需 DBA 权限,且可能影响全局
QUERY_REWRITE_INTEGRITY 设为 ENFORCED 时的硬性要求
默认值是 ENFORCED,意味着 Oracle 要求“绝对可信”才敢用物化视图。它不是凭空判断,而是严格检查三样东西:
- 基表必须有
VALIDATED状态的主键或外键(ALTER TABLE t ADD CONSTRAINT pk_t PRIMARY KEY(id) ENABLE VALIDATE;) - 所有被引用的基表都得建好物化视图日志,且含
INCLUDING NEW VALUES - 日志中
SEQUENCE列必须显式包含物化视图 SELECT 中出现的所有列,比如CREATE MATERIALIZED VIEW LOG ON sales WITH ROWID, SEQUENCE (prod_id, cust_id, amount) INCLUDING NEW VALUES;
缺任何一项,DBMS_MVIEW.EXPLAIN_REWRITE 都会返回 integrity violation,而不是默默跳过。
物化视图定义里哪些写法会让重写直接失效?
Oracle 对“确定性”极其敏感。以下任意一种都会让优化器当场放弃重写:
- 用了
SYSDATE、USER、DBMS_RANDOM.VALUE等非确定性函数 - SELECT 列中含
ROWNUM或窗口函数未加确定性排序(如ROW_NUMBER() OVER (ORDER BY NULL)) - 表达式不严格等价:物化视图里是
UPPER(name),而查询写的是name = 'ABC';或者物化视图用TO_CHAR(dt, 'YYYY-MM-DD'),查询却用dt >= DATE '2026-01-01'
这类问题不会报错,但 EXPLAIN_REWRITE 会明确提示 no match —— 它不是找不到,而是认为语义不安全。
怎么确认某条 SQL 真的被重写了?
别信 EXPLAIN PLAN,它只是预估。真实路径只在执行后才固化:
- 开启真实执行计划追踪:
SET AUTOTRACE ON EXPLAIN STATISTICS;再运行 SQL,看输出里是否出现物化视图的物理名(如MV_SALES_SUM) - 查
V$SQL_PLAN:SELECT object_name, operation FROM v$sql_plan WHERE sql_id = '<your_sql_id>' AND object_name LIKE 'MV%'; - 最准的验证是
DBMS_MVIEW.EXPLAIN_REWRITE:传入 SQL 文本和物化视图名,它会告诉你卡在哪一步,比如stale data(刷新滞后)、unmatched column(列不对应)
真正容易被忽略的是:物化视图日志不是“建了就行”,而是必须带 INCLUDING NEW VALUES,且 SEQUENCE 列要和物化视图 SELECT 列完全对齐——少一个字段,FAST 刷新失败,重写也大概率被拒。


















