Oracle - 子查询的物化视图
Posted
技术标签:
【中文标题】Oracle - 子查询的物化视图【英文标题】:Oracle - Materialized Views on Subquery 【发布时间】:2021-08-12 13:12:37 【问题描述】:从文档中我了解到,我们无法在其中包含子查询的查询上创建物化视图。 所以我创建了一个普通的 oracle 视图并使用该普通视图创建了一个物化视图
CREATE MATERIALIZED VIEW TEST_MV BUILD IMMEDIATE
REFRESH FORCE AS
SELECT * FROM "MAIN_LOOKUP"
这个“MAIN_LOOKUP”视图中有很多子查询
帮助我理解以下几点
-
“主要查找”视图具有将实时使用的表和数据更改的高机会。由于该选项指定为 FORCE,它会自动刷新吗?
我无法包含选项 ENABLE QUERY REWRITE 其说“不支持查询重写的表达式”。如果未指定该选项,创建的 MV 会不会有任何问题?
我们是否应该为所有基础表创建物化视图日志?
谢谢
【问题讨论】:
【参考方案1】:根据documentation:
指定 FORCE 表示当发生刷新时,Oracle 数据库 如果可能,将执行快速刷新或完全刷新 如果无法快速刷新。
这指定将发生哪种类型的刷新:如果可能,快速(增量)刷新,否则完全刷新。它不会自动刷新任何内容。
ON COMMIT
选项将自动更新 MV,但如果源表高度活跃,则会显着影响应用程序性能:
指定 ON COMMIT 表示每当 数据库提交一个在主表上操作的事务 物化视图。该条款可能会增加完成所需的时间 提交,因为数据库执行刷新操作为 提交过程的一部分。
换句话说,这将序列化所有源表上的所有事务,强制每个表上的每次提交都刷新 MV。
默认情况下不启用查询重写,因此不包括它不会影响任何事情。如果您想要启用它,那么它必须满足以下条件:
启用查询重写受以下限制:
只有当所有用户定义的函数都在 物化视图是确定的。
只有当语句中的表达式是 可重复的。例如,您不能包括 CURRENT_TIME 或 USER, 序列值(例如 CURRVAL 或 NEXTVAL 伪列),或 SAMPLE 子句(它可以对不同的行进行采样作为 物化视图更改)。
如果您的 MV 符合 FAST REFRESH 的条件,则在源表上创建 MV 日志。您仍然需要手动刷新 MV,或者使用计划的作业。
FAST 刷新受以下限制:
当您在创建时指定 FAST 刷新时,Oracle 数据库会验证 您正在创建的物化视图有资格快速 刷新。当您在 ALTER 中将刷新方法更改为 FAST 时 MATERIALIZED VIEW 语句,Oracle 数据库不执行此操作 确认。如果物化视图不符合快速 刷新,然后 Oracle 数据库在您尝试 刷新此视图。
如果定义了实体化视图,则不符合快速刷新的条件 查询包含分析函数或 XMLTable 函数。
如果定义了实体化视图,则不符合快速刷新的条件 查询引用了一个定义了 XMLIndex 索引的表。
如果物化视图的任何列是 加密。
documentation 对使用快速刷新物化视图有几个额外的限制,其中许多是有条件的。做好功课并阅读要求和例外情况,以确定它们是否适用于您的具体情况。实际例子也可以查看各种在线教程和例子,比如this one。
【讨论】:
非常感谢。 FAST 刷新是否需要源表上的主键? 快速刷新也可以使用 ROWID(实际上可能需要),但您需要阅读文档中的所有其他限制和要求。我在我的答案中添加了更多链接,其中包含更多详细信息。 感谢您提供详细信息。我正在创建一个 MV,而该 MV 又使用另一个 MV。这样做是因为 MV 不支持子查询。那么引用是如何发生的?主 MV 和子 MV 都定义为 FAST 和 ON COMMIT 我会强烈不鼓励使用分层的ON COMMIT
物化视图,尤其是在源表处于活动状态时。 ON COMMIT 意味着源表上的每个事务都会触发每个分层 MV 的刷新,并且多个并发事务可能最终会等待其他 MV 刷新完成才能开始。这几乎肯定会以非常非常糟糕的方式影响您的应用程序性能,即使使用 FAST 刷新也是如此。从性能/可扩展性的角度来看,您最好使用计划作业每分钟刷新一次。
还要考虑到,如果任何层的 ON COMMIT 刷新出现问题,它会强制你的应用程序事务失败并回滚。您的应用程序是否旨在处理该问题?如果您确实需要实时访问更改的数据,那么我建议您使用普通视图而不是物化视图。您使用物化视图背后的驱动决策是什么?以上是关于Oracle - 子查询的物化视图的主要内容,如果未能解决你的问题,请参考以下文章