Необходимо из таблицы table_remote@dblink объемом 270 ГБ, выбрать только лишь те строки, которые соответствуют строкам из локальной таблицы table_dict. Результат выборки сохранить в локальную таблицу table_local. Предварительные выборки показали, что результат составит примерно 100 МБ.
DECLARE
CURSOR cr_data IS
SELECT
/*+ driving_site(tr)*/
tr.*
FROM table_remote@dblink tr
join table_dict td
ON ( tr.col_1 = td.col_2);
TYPE t_cr_row IS TABLE OF cr_data%ROWTYPE;
v_cr_row t_cr_row;
BEGIN
OPEN cr_data;
LOOP
FETCH cr_data BULK COLLECT
INTO v_cr_row limit 10000;
EXIT WHEN v_cr_row.count = 0;
FORALL i IN 1..v_cr_row.count
INSERT INTO table_local VALUES v_cr_row(i);
COMMIT;
END LOOP;
CLOSE cr_data;
END;
/
На локальном сервере создаём таблицу (table_local), затем, используя анонимный PL/SQL блок и курсор, загружаем отфильтрованные данные из table_remote@dblink:
CURSOR cr_data IS
SELECT
/*+ driving_site(tr)*/
tr.*
FROM table_remote@dblink tr
join table_dict td
ON ( tr.col_1 = td.col_2);
TYPE t_cr_row IS TABLE OF cr_data%ROWTYPE;
v_cr_row t_cr_row;
BEGIN
OPEN cr_data;
LOOP
FETCH cr_data BULK COLLECT
INTO v_cr_row limit 10000;
EXIT WHEN v_cr_row.count = 0;
FORALL i IN 1..v_cr_row.count
INSERT INTO table_local VALUES v_cr_row(i);
COMMIT;
END LOOP;
CLOSE cr_data;
END;
/
В этом варианте решения следует принять во внимание то, что в списке полей таблицы table_remote@dflink не должно быть LOB-полей. LOB-поля не возможно выбирать по dblink. При такой попытке возникает ошибка ORA-22992: cannot use LOB locators selected from remote tables.
Для копирования remote таблиц c LOB-полями необходимо создавать промежуточные таблицы методом CTAS (CREATE TABLE AS SELECT).
Рассмотрим другие варианты решения этой задачи.
1. На локальном сервере запускаем команду на создание промежуточной таблицы с выборкой данных и соединением таблиц - CTAS:
CREATE TABLE table_local AS
SELECT /*+ driving_site(tr)*/ tr.*
SELECT /*+ driving_site(tr)*/ tr.*
FROM table_remote@dblink tr
join table_dict td
ON ( tr.col_1 = td.col_2 );
join table_dict td
ON ( tr.col_1 = td.col_2 );
Используя хинт driving_site мы просим СУБД выполнить соединение таблиц на удаленном сервере, предполагая, что переправка данных таблицы table_dict займет меньше времени, чем переправка данных таблицы table_remote@dblink объёмом 270 ГБ. Но это решение не будет работать, потому что хинт driving_site в DDL не будет функционировать.
2. На локальном сервере создаём таблицу, затем используя INSERT, загружаем отфильтрованные данные из table_remote@dblink :
INSERT INTO table_local
SELECT /*+ driving_site(tr)*/ tr.*
FROM table_remote@dblink tr
join table_dict td
ON ( tr.col_1 = td.col_2 );
SELECT /*+ driving_site(tr)*/ tr.*
FROM table_remote@dblink tr
join table_dict td
ON ( tr.col_1 = td.col_2 );
Это решение также не является оптимальным по той же причине - хинт driving_site не будет работать в DML.