Самый быстрый способ скопировать таблицы в одной базе данных - использовать параллелизм Oracle, а не параллелизм. Запускайте SQL поочередно, параллельно, вместо одновременного запуска нескольких операторов.
Слова параллелизма и параллелизма означают немного разные вещи в Oracle. Параллелизм - это функция, доступная в Enterprise Edition; База данных создаст параллельные сеансы для разделения и мониторинга работы. Параллельность - это когда вы вручную создаете и отслеживаете отдельные процессы, которые делают что-то одновременно.
Параллелизм обычно намного проще, чем параллелизм. Часто требуется только одна подсказка, чтобы включить его (хотя есть много сложных последствий этих простых подсказок). Параллелизм требует от вас создания и мониторинга заданий планировщика.
Параллелизм обычно намного быстрее, чем параллелизм. Oracle, вероятно, может лучше распределять работу, чем вы. Параллелизм разбивает работу на гранулы и распределяет их по параллельным процессам по мере необходимости. Это не идеально, но обычно довольно хорошо. Сравните это с параллелизмом, когда вы отвечаете за поиск таблиц X, которые обрабатываются одинаково быстро. Найти таблицы одинакового размера X сложнее, чем вы думаете, а неправильно понять - это плохо для производительности.
Вот процедура, которая загружает набор таблиц с параллелизмом. Вы, вероятно, захотите убедиться, что каждый оператор получает прямую запись и параллелизм - вам может потребоваться отключить внешние ключи, включить NOLOGGING, отключить триггеры и т. Д. Чтобы получить это право, могут потребоваться часы.
create or replace procedure parallel_load
--Purpose: Copy data from source tables to destination tables.
--This procedure truncates target tables - there is no turning back!
(
p_source_schema in varchar2,
p_target_schema in varchar2,
p_tables sys.odcivarchar2list,
p_dop number
) authid current_user is
v_sql varchar2(32767);
begin
--Enable parallel DML for parallel writing.
execute immediate 'alter session enable parallel dml';
--Loop through the tables.
for i in 1 .. p_tables.count loop
begin
--Truncate the target table.
execute immediate 'truncate table '||p_target_schema||'.'||p_tables(i);
--Create parallel insert.
v_sql :=
replace(replace(replace(replace(
q'[
insert /*+ parallel(#DOP#) */ into #TARGET_SCHEMA#.#TABLE_NAME#
select * from #SOURCE_SCHEMA#.#TABLE_NAME#
]'
, '#DOP#', p_dop)
, '#TARGET_SCHEMA#', p_target_schema)
, '#TABLE_NAME#', p_tables(i))
, '#SOURCE_SCHEMA#', p_source_schema);
--Execute the parallel insert.
execute immediate v_sql;
--Must commit if direct-path writes are used.
commit;
exception when others then
raise_application_error(-20000, 'Error with this SQL: '||v_sql||chr(10)||
sys.dbms_utility.format_error_stack||sys.dbms_utility.format_error_backtrace);
end;
end loop;
end;
/
Вот пример вызова. (Найти правильный DOP сложно, попробуйте поэкспериментировать с разными числами и посмотрите на параметры cpu_count
и %parallel%
в V$PARAMETER
.)
begin
parallel_load(
p_source_schema => 'source_schema',
p_target_schema => 'target_schema',
p_tables => sys.odcivarchar2list('test1', 'test2', 'test3'),
p_dop => 8
);
end;
/
Вы почти наверняка НЕ хотите использовать DBMS_SCHEDULER, программу ETL или команду COPY. Эти решения будут намного сложнее и медленнее, чем параллелизм. (Не в обиду тем, кто разместил эти ответы. Они были размещены
перед критическим комментарием, объясняющим, что таблицы находятся в одной базе данных.)