检测Oracle表中的数据是否已更改

时间:2015-04-14 15:03:22

标签: oracle triggers database-performance

我正在寻找最佳性能解决方案来检测Oracle表中的数据是否已更改。这将用于启动使用来自相同表的大量数据的计算。这将是昂贵的轮询所有数据以跟踪变化。这种变化很少发生。

我已经分析了以下问题的解决方案。

  • ORA_ROWSCN:要慢一点,会进行全表扫描。
  • Oracle审核:无法在我的环境中进行设置。
  • DBMS_ALERT:作家无法发出信号。

然后我提出了以下简单的想法。向表添加触发器,在插入,更新或删除时递增序列。我知道这将会实现,如果回滚,但我可以承担一些误报。我的计算服务然后轮询序列当前值以检测可能的更改(=非常便宜的查询)

CREATE OR REPLACE TRIGGER trg_change_tracker
       before insert or update or delete on mytable
declare
    dummy number;
begin
     select seq_event_seqno.nextval into dummy from dual;
end;

这听起来怎么样?有任何陷阱吗?

编辑:是的,有一个市长陷阱:当作者阻止提交时,读者在提交者提交之前看到新的序列值并查询更改。

1 个答案:

答案 0 :(得分:0)

我建议您添加一些触发剂: 当您的轮询查看序列的更改时,您可以检查感兴趣的表上的已打开事务(如果存在),然后跳过当前重新计数。

UPD: 此外,您可以保存已打开事务的最小SCN,如果频繁更改表,则不会冻结

UPD2: 这是一些启发式改进,而不是完整的问题解决方案。如果你每次看到打开的交易时都会跳过重新计算,那么你可以在桌面上频繁(并且可能很长)DML的情况下冻结很多时间。 我的意思是,当seq被更改并且轮询看到您桌面上的已打开事务时,您可以从v $ transaction存储min(start_scn),并且当轮询在下次看到打开的事务时,您可以将当前min(start_scn)与sotred min(start_scn),如果当前更大,那么某些机会是时候重新计算了。