2

出于性能原因,我需要将表从外部数据库复制到内部数据库。几个应用程序将使用这个本地数据库来进行连接和比较数据。我只需要每小时左右复制一次,但如果有性能解决方案,我宁愿每 5 到 10 分钟复制一次。

最好的复制方式是什么?首先想到的是 DROP 然后 CREATE:

DROP TABLE clonedTable;
CREATE TABLE clonedTable AS SELECT * from foo.extern@data.sourceTable;

应该有更好的方法吧?希望有一个原子解决方案来避免表不存在但有人可能会尝试查询它的那几分之一秒。

4

1 回答 1

2

最简单的可能解决方案是设置为每小时刷新一次的物化视图。

CREATE MATERIALIZED VIEW mv_cloned_table
  REFRESH COMPLETE 
  START WITH sysdate + interval '1' minute
  NEXT sysdate + interval '1' hour
AS
SELECT *
  FROM foo.external_table@database_link;

这将删除当前中的mv_cloned_table所有数据,将表中的所有数据插入外部数据库中,然后安排自己在完成后一小时再次运行(因此实际上将是 1 小时 + 无论两次刷新之间需要多长时间)。

有很多方法可以优化这一点。

  • 如果拥有源数据库的人愿意接受它,您可以要求他们在源表上创建物化视图日志。这将允许您的物化视图仅复制应该更有效的更改,并允许您更频繁地安排刷新。
  • 如果您与拥有源数据库的人合作,您还可以使用 Streams 而不是物化视图,这可以让您近乎实时地复制更改(通常会延迟几秒钟)。这在源系统上也往往比维护物化视图日志更有效。但是要让一切正常工作往往需要更多的管理时间——物化视图的灵活性和效率要低得多,但配置起来很容易。
  • 如果您不介意在刷新期间表为空(它会存在,只是没有数据),您可以对物化视图进行非原子刷新,这将执行TRUNCATE直接路径INSERT而不是aDELETE和常规路径INSERT。前者效率更高,但意味着当您在本地服务器上进行连接和数据比较时,表会显示为空,这在这种情况下似乎不太合适。

如果您想沿着源端创建物化视图日志的路径进行下去,以便您可以在源端进行增量刷新,假设源表具有主键,您会要求他们

CREATE MATERIALIZED VIEW LOG ON foo.external_table
  WITH PRIMARY KEY
  INCLUDING NEW VALUES;

您将创建的物化视图将是

CREATE MATERIALIZED VIEW mv_cloned_table
  REFRESH FAST
  START WITH sysdate + interval '1' minute
  NEXT sysdate + interval '1' hour
  WITH PRIMARY KEY
AS
SELECT *
  FROM foo.external_table@database_link;
于 2012-12-19T00:14:51.000 回答