Oracle 19c不支持实时物化视图,ON QUERY COMPUTATION与QUERY REWRITE互斥且不可共存;必须选择其一:前者提供动态最新结果但不参与重写,后者依赖刷新快照并需严格配置参数、权限、语义匹配及状态校验才能生效。
oracle 19c 不支持“实时物化视图”这个概念——on query computation 是唯一接近实时的机制,但它不是传统意义上的物化视图,也不参与查询重写(query rewrite),两者互斥。
ON QUERY COMPUTATION 和 QUERY REWRITE 不能共存
你无法在同一个物化视图上同时指定 ENABLE QUERY REWRITE 和 ON QUERY COMPUTATION。Oracle 明确禁止这种组合:
-
ON QUERY COMPUTATION绕过物化视图日志和刷新逻辑,每次查询都动态合并基表最新变更(通过内部变更跟踪),结果“总是最新”,但执行计划里永远显示访问基表 + 变更计算,不会出现物化视图名 -
QUERY REWRITE要求物化视图内容稳定、可预测,且优化器能基于统计信息估算成本;而ON QUERY COMPUTATION的运行时行为不可静态评估,所以优化器直接跳过重写路径 - 尝试建带两者子句的 MV 会报错:
ORA-32340: ON QUERY COMPUTATION cannot be specified with ENABLE QUERY REWRITE
想用查询重写,就必须接受刷新延迟
真正能被 QUERY REWRITE 拦截的物化视图,必须是已刷新、状态为 VALID、且内容与基表某一时点一致的快照。这意味着:
-
REFRESH FAST ON COMMIT是最接近“准实时”的选择:事务提交后立即更新 MV,但依赖物化视图日志,且要求基表有ROWID或主键约束,并显式声明WITH PRIMARY KEY或WITH ROWID -
REFRESH FAST ON DEMAND配合定时任务(如 DBMS_SCHEDULER)可控制延迟粒度(例如每5分钟刷一次),但需确保日志表不成为瓶颈——分区表的日志仍是普通堆表,建议单独指定高性能表空间 -
REFRESH COMPLETE无法用于高频报表,因为全量重建开销大,且刷新期间 MV 不可用或返回陈旧数据
验证是否真走重写,别信 EXPLAIN PLAN
EXPLAIN PLAN FOR SELECT ... 永远不会显示物化视图被重写——它只展示“不启用重写时的执行计划”。正确验证方式只有:
- 先执行:
EXEC DBMS_MVIEW.EXPLAIN_REWRITE('SELECT SUM(sales) FROM fact_sales WHERE dt >= DATE''2024-01-01''', 'mv_sales_daily'); - 再查:
SELECT rewrite_mechanism, message FROM rewrite_table; - 成功标志是
REWRITE_MECHANISM字段值为TEXT_MATCH或GENERAL;UNREWRITTEN表示语义不匹配(比如用了TO_CHAR(dt, 'YYYY-MM')而 MV 里是TRUNC(dt, 'MM'));FAILED通常是权限或参数缺失
最关键却最容易被忽略的三点
即使 MV 定义正确、刷新正常、索引也建了,仍可能静默失效:
-
QUERY_REWRITE_ENABLED必须在**执行查询的那个会话**中为TRUE——Spring Boot + HikariCP 连接池复用会话,开发环境手动ALTER SESSION了,生产没配,实际就是FALSE - 用户必须有
QUERY REWRITE权限(不是CREATE MATERIALIZED VIEW权限),否则即使参数开了也跳过重写 - 基表若定义了函数索引、虚拟列或复杂约束,可能干扰优化器语义推导;建议先用
DBMS_MVIEW.EXPLAIN_REWRITE检查,而不是反复调优 SQL


















