Выберите и Вставьте через dblink

Я испытываю немного затруднений из-за выбора во вставку через dblink в оракуле 10. Я использую следующее утверждение:

INSERT INTO LOCAL.TABLE_1 ( COL1, COL2) 
SELECT  COL1, COL2
FROM REMOTE.TABLE1@dblink s
WHERE COL1 IN ( SELECT COL1 FROM WORKING_TABLE)

Когда я выполняю оператор, следующее - то, что выполняется против удаленного сервера на Ссылке DB:

SELECT /*+ OPAQUE_TRANSFORM */ "COL1", "COL2"
FROM "REMOTE"."TABLE1" "S"

Если я выполняю выбор только и не делаю, вставка в следующее выполняется:

SELECT /*+ */ "A1"."COL1"
     , "A1"."COL2"
  FROM "REMOTE"."TABLE1" "A1"
 WHERE "A1"."COL1" =
   ANY ( SELECT "A2"."COL1"
       FROM "LOCAL"."TABLE1"@! "A2")

Проблема находится в случае вставки, enitre таблицу вытягивают через dblink и затем ограничивают локально, который занимает немного времени, учитывая размер таблицы. Там какая-либо причина добавляет, что вставка изменила бы поведение этим способом?

8
задан Domtar 17 March 2010 в 14:15
поделиться

4 ответа

Вы можете использовать подсказку driving_site. Здесь есть хорошее объяснение: http://www.dba-oracle.com/t_sql_dblink_performance.htm

3
ответ дан 5 December 2019 в 17:36
поделиться

Когда дело доходит до DML, oracle игнорирует любые подсказки drive_site и выполняет инструкцию на целевом сайте. Поэтому я сомневаюсь, что вы сможете это изменить (даже используя подход WITH, описанный выше). Возможный обходной путь - вы можете создать синоним для LOCAL.TABLE1 в удаленной базе данных и использовать его в своем операторе INSERT.

3
ответ дан 5 December 2019 в 17:36
поделиться

Насколько велика WORKING_TABLE? Если он достаточно мал, можно попробовать выбрать из work_table в коллекцию, а затем передать элементы этого сбора в виде элементов в список 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;
/
0
ответ дан 5 December 2019 в 17:36
поделиться

Использование предложения 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
2
ответ дан 5 December 2019 в 17:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: