【发布时间】:2013-05-16 13:28:10
【问题描述】:
在 Oracle 数据库中有一个pseudocolumn which's called ora_rowscn。如果检索到它,它将显示该行最近更改的 SCN(如文档中所述)。
还有一个选项 rowdependencies 或 CREATE TABLE 可以为每一行而不是整个数据块(默认)打开 SCN 的存储。
因此,我使用此列的值来指示哪些行已更新并且需要上传到另一个数据库。
让我们考虑这个例子:
-
架构
S1中有一个表T1,其中包含数百万条记录(常规查询无法承受对表的全面扫描)。CREATE TABLE T1 { A INTEGER PRIMARY KEY, B VARCHAR2(100), C DATE } / -
有
S2, S3, S4, S5..的架构,每个架构中都有T2的表。CREATE TABLE T2 { A INTEGER } / T2中只有一行,但T2.A的值在不同的架构中可能不同。
所以,我需要在每个模式 (S2, S3, S4...) 中检索来自 S1.T1 的所有行,其中 ora_rowscn 的值大于 S*.T2.A(然后我使用这个数据块)。
获取这些行后,我用当前系统 SCN (dbms_flashback.get_system_change_number) 重写 S*.T2.A 的值。
任何架构的以下查询都在这里:
查询 1:
SELECT * FROM S1.T1 WHERE ora_rowscn > (SELECT A FROM T2);
查询 2(它在我完成上一个查询返回的数据集的工作时执行):
UPDATE T2 SET A = dbms_flashback.get_system_change_number;
问题是查询 1 的性能不可接受(对表 S1.T1 进行全面扫描)并且无法为列 ora_rowscn 建立索引。
问题:有哪些方法可以提高查询 1 的性能?
【问题讨论】:
-
查询 1 和 2 假设每分钟执行一次。
-
为什么不直接使用闪回查询表
select * from S1.T1 as of timestamp (sysdate - 1)?? -
也许是因为它完全不同?我不需要过去的数据,我需要自上次查询以来的所有更新数据
-
希望您的真实版本考虑到在您开始查询 1 和从查询 2 获取当前 SCN 之间的 SCN 增量?否则,每次运行的数据都会出现漏洞,无论你跑得有多快。 (使用 SCN 或
last_updated字段)。我想解决这个问题的明显方法是在T2中存储两个值并在它们之间进行查询。 -
嗯,是的,你是对的。这就是为什么我在执行查询1之前实际上将当前SCN的值保存在一个变量中,完成后我将保存的值写入
T2,这里为了简化问题省略了这个事实