刷新视图的结果时?

时间:2014-11-22 02:54:14

标签: sql oracle view materialized-views

我在表格中实现了视图的结果。 我想知道他们是否有办法知道此视图的结果何时更改以刷新它。 物化视图和结果缓存可以做到这一点,但我不想使用这两种技术。 他们是回答这个问题的另一种方式吗?

事实上,我们有一个通用系统,每隔n分钟实现并刷新一次视图。刷新的成本可能很高,我试图知道我们是否可以知道基础数据是否发生了变化。

我们不使用实体化视图,因为完全刷新会截断表格,并且仅在具有主键的表格上快速刷新。

结果缓存无法完成工作,因为我们没有足够的内存。

所以我想知道我们是否可以使用一种技术来了解自上次刷新以来视图的基础数据是否发生了变化

3 个答案:

答案 0 :(得分:1)

你可以有一个看起来像这样的标志表:

CREATE TABLE FlagTable
  SourceTable varchar(30),
  UpdateDate DATETIME,
  Handled CHAR(1) DEFAULT 'N'

在基表上创建一个触发器,在表的INSERT,UPDATE或DELETE中,使用基表的名称将记录插入FlagTable

如果要检查刷新,只需选择WHERE Handled =' N',刷新伪视图,然后设置Handled =' Y'

答案 1 :(得分:1)

您可以通过设置mat_view with refresh on commit选项,以及在提交时刷新 fast ,以更简单的方式完成所有这些操作。这将保证每次发生更改时视图将仅刷新新行(与完全刷新相比,视图后面的查询作为整体执行)。

现在最后一种方法可能会导致很多问题,因为刷新快速刷新选项有限制,如果你不能遵守它,你就不能使用它。但是,如果您可以将此设置为在提交时刷新完成,则可能会不时地根据您的建议使系统变慢,并且还表明您无法隔离更改源。< / p>

如果您想查看最频繁更改的位置,建议您使用自定义表(每天)在mat_view后面存储查询的每日结果。然后几天后,做一些像:

select * from daily_table_day_one
minus
select * from mat_view
union all
select * from mat_view
minus
select * from daily_table_day_one

因为ORA_ROWSCN的方法并不总是有效。带有触发器的方法在有限的情况下有效,如果不需要在100个表上创建这些触发器......这是荒谬的。

当您找到更改源 - 例如来自某些表的多个列时,您可能会考虑重写mat_view查询,遵循一些DW原则并创建查询的星型模式。这将对查询进行分段,并且肯定会加快查询速度。检查负载的来源 - 如果这些昂贵的连接,扫描无法避免的任何内容,可能会破坏对较小查询的查询,如果您也可以实现它们,也许您可​​以通过刷新设置它们快速提交。

这完全取决于实施。如果你可以在这里给出一个查询或其中一部分的例子,通过解释计划,我们也可以为你提供具体的解决方案。

欢呼声

答案 2 :(得分:0)

这只是一种启发式方法,但作为视图刷新过程的一部分,您可以查询并存储源表中的最大ora_rowscn和行数。然后定期检查这些值以查看其中一些表是否已更改。

select MAX(ora_rowscn), COUNT(*) 
  into last_change_scn, last_change_length 
  from src_table;

如果我没错,那么您的表格中是否有任何插入或更新,MAX(ora_rowscn)会发生变化。如果有一些删除,COUNT(*)会改变。

在黑暗的一面,查询MAX(ora_rowscn)将触发全表扫描。当然,这不能告诉您这些更改是否会影响视图。