0

我担心的是,我有一个远程视图 abc@DBLINK 和一个本地表 xyz。我需要映射一个远程视图和一个本地表,并从 abc@DBLINK 视图中获取少量数据并插入到其他一些本地表中,比如 pst。IE

INSERT INTO pst 
SELECT remote.col1, remote.col2, remote.col3, remote.col4 
FROM 
  abc@dblink remote, 
  xyz local 
WHERE remote.col1=local.col1 
  AND remote.col2=local.col2;

有人可以向我提供任何建议,我可以如何更快地完成这项任务?请注意 abc@DBLINK 包含大量数据,并且索引存在于本地表 col1 和 col2 上。

4

2 回答 2

1

一种可能的方法是使用DRIVING_SITE 提示在远程站点上强制执行 JOIN :

INSERT INTO pst 
SELECT /*+DRIVING_SITE(abc)*/ 
  remote.col1, remote.col2, remote.col3, remote.col4 
FROM 
  abc@dblink remote, 
  xyz local 
WHERE remote.col1=local.col1 
  AND remote.col2=local.col2;

(我似乎记得在做 anINSERT而不是 plain时有一个限制SELECT,但我现在在文档中找不到它 - 您可能必须切换到从远程获取游标然后执行的 PL/SQL 过程INSERT当地人从提示中受益)。

更新

在对本地表执行操作时, Oracle 确实会忽略该DRIVING_SITE提示。INSERT乔纳森刘易斯有一篇有趣的文章解释了这个原因。

这样你就可以:

  • 切换到一个 PL/SQL 过程,该过程SELECT .. BULK COLLECT使用DRIVING_SITE提示并执行本地INSERT
  • 远程创建一个连接视图,并将该视图用于INSERT

更新 2

这是使用 PL/SQL 方法的完整解决方案;它使用一个对象类型和一个关联的集合(我使用了一个虚拟查询作为输入,它只生成 9500 行而不是原始的 DB 链接,但调整它非常简单):

create table pst(col1 number, col2 number, col3 number, col4 number);

create type pst_t as object (
  col1 number,
  col2 number,
  col3 number,
  col4 number);

create type pst_table_t as table of pst_t;

declare
  v_coll pst_table_t;
  C_LIMIT constant pls_integer := 1000;
  cursor v_cur is 
    select 
      pst_t(level, level*2, level*3, level*4)
    from dual
    connect by level <= 9500;
begin
  open v_cur;
  loop
    fetch v_cur bulk collect into v_coll limit C_LIMIT;
    insert into pst(col1,col2,col3,col4) 
      select col1,col2,col3,col4 from table(v_coll);    
    exit when v_coll.count < C_LIMIT;
  end loop;
end;  
于 2015-05-20T08:13:31.707 回答
0

除了其他建议之外,还有其他一些方法:-

  • 检查两台服务器之间的延迟(本地到 DBLink 服务器)。网络延迟在其中起着重要作用。
  • 如果 DBLink 数据库上的数据不经常更改,那么您可以将数据插入到本地数据库上的某个登陆表并不时更新它,并将该登陆表用于您的查询,而不是使用 DBLink。
于 2016-08-25T08:34:18.990 回答