出于性能原因,我需要将表从外部数据库复制到内部数据库。多个应用程序将使用此本地数据库进行连接和比较数据。我只需要每小时左右复制一次,但如果有性能解决方案,我更愿意每 5 到 10 分钟复制一次。
最好的复制方法是什么?首先想到的是 DROP 然后 CREATE:
DROP TABLE clonedTable;
CREATE TABLE clonedTable AS SELECT * from <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d4b2bbbbfab1aca0b1a6ba94b0b5a0b5faa7bba1a6b7b180b5b6b8b1" rel="noreferrer noopener nofollow">[email protected]</a>;
一定有更好的方法吧?希望有一个原子解决方案来避免表不存在但有人可能会尝试查询它的情况。
最佳答案
最简单的解决方案是设置每小时刷新一次的物化 View 。
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 小时 + 刷新之间刷新所需的时间)。
有很多方法可以优化这一点。
- 如果拥有源数据库的人愿意,您可以要求他们在源表上创建物化 View 日志。这将允许您的物化 View 仅复制更改,这应该更加高效,并且允许您更频繁地安排刷新。
- 如果您与拥有源数据库的人员合作,您还可以使用 Streams 而不是具体化 View ,这样您就可以近乎实时地复制更改(几秒钟的延迟很常见)。这在源系统上也往往比维护物化 View 日志更有效。但它往往需要更多的管理时间才能让一切正常工作——物化 View 的灵活性和效率要低得多,但配置起来却很容易。
- 如果您不介意刷新期间表为空(它会存在,只是没有数据),您可以对物化 View 进行非原子刷新,这将执行
TRUNCATE
后跟直接路径INSERT
,而不是DELETE
和传统路径INSERT
。前者效率更高,但意味着当您在本地服务器上进行联接和数据比较时,表会显示为空,这在这种情况下似乎不太合适。
如果您想让源端创建一个物化 View 日志,以便您可以在源端进行增量刷新,假设源表有主键,您会要求他们
CREATE MATERIALIZED VIEW LOG ON foo.external_table
WITH PRIMARY KEY
INCLUDING NEW VALUES;
您将创建的物化 View 将是
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;
关于sql - 将表从外部数据库复制到内部数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13943513/