我在oracle 10中跨dblink的select into插入时遇到了一些麻烦。我使用以下语句:
INSERT INTO LOCAL.TABLE_1 ( COL1, COL2)
SELECT COL1, COL2
FROM REMOTE.TABLE1@dblink s
WHERE COL1 IN ( SELECT COL1 FROM WORKING_TABLE)
当我运行语句时,以下是在DB Link上对远程服务器运行的内容:
SELECT /*+ OPAQUE_TRANSFORM */ "COL1", "COL2"
FROM "REMOTE"."TABLE1" "S"
如果我只运行select而不执行以下插入运行:
SELECT /*+ */ "A1"."COL1"
, "A1"."COL2"
FROM "REMOTE"."TABLE1" "A1"
WHERE "A1"."COL1" =
ANY ( SELECT "A2"."COL1"
FROM "LOCAL"."TABLE1"@! "A2")
问题出在插入的情况下,enitre表被拉过dblink然后限制localy,这需要花费相当多的时间给定表大小。是否有任何理由添加插入会以这种方式改变行为?
答案 0 :(得分:3)
您可能想要使用driving_site提示。这里有一个很好的解释: http://www.dba-oracle.com/t_sql_dblink_performance.htm
答案 1 :(得分:3)
说到DML,oracle选择忽略任何driving_site提示并在目标站点执行语句。所以我怀疑你是否能够改变它(甚至使用上述的WITH方法)。一种可能的解决方法是,您可以在远程数据库上为LOCAL.TABLE1创建一个同义词,并在INSERT语句中使用它。
答案 2 :(得分:2)
利用WITH子句可以优化对工作集的检索:
WITH remote_rows AS
(SELECT /*+DRIVING_SITE(s)*/COL1, COL2
FROM REMOTE.TABLE1@dblink s
WHERE COL1 IN ( SELECT COL1 FROM WORKING_TABLE))
INSERT INTO LOCAL.TABLE_1 ( COL1, COL2)
SELECT COL1, COL2
FROM remote_rows
答案 3 :(得分:2)
Oracle将忽略insert语句的driving_site提示,因为DML总是在本地执行。执行此操作的方法是使用驱动站点提示创建游标,然后使用bulkcollect / forall循环遍历游标并插入到目标本地表中。
答案 4 :(得分:0)
WORKING_TABLE有多大? 如果它足够小,您可以尝试从work_table中选择一个集合,然后将该collect的元素作为元素传递到IN列表中。
declare
TYPE t_type IS TABLE OF VARCHAR2(60);
v_coll t_type;
begin
dbms_application_info.set_module('TEST','TEST');
--
select distinct object_type
bulk collect into v_coll
from user_objects;
--
IF v_coll.count > 20 THEN
raise_application_error(-20001,'You need '||v_coll.count||' elements in the IN list');
ELSE
v_coll.extend(20);
END IF;
insert into abc (object_type, object_name)
select object_type, object_name
from user_objects@tmfprd
where object_type in
(v_coll(1), v_coll(2), v_coll(3), v_coll(4), v_coll(5),
v_coll(6), v_coll(7), v_coll(8), v_coll(9), v_coll(10),
v_coll(11), v_coll(12), v_coll(13), v_coll(14), v_coll(15),
v_coll(16), v_coll(17), v_coll(18), v_coll(19), v_coll(20)
);
--
dbms_output.put_line(sql%rowcount);
end;
/
答案 5 :(得分:0)
插入基数提示似乎在11.2中起作用
INSERT /*+ append */
INTO MIG_CGD30_TEST
SELECT /*+ cardinality(ZFD 400000) cardinality(CGD 60000000)*/
TRIM (CGD.NUMCPT) AS NUMCPT, TRIM (ZFD.NUMBDC_NEW) AS NUMBDC
FROM CGD30@DBL_MIG_THALER CGD,
ZFD10@DBL_MIG_THALER ZFD,
EVD01_ADS_DR3W2 EVD