Самый быстрый способ вставить большое количество строк - использовать параллелизм и прямую запись:
alter session enable parallel dml;
insert /*+ append parallel */ into test1
select -a, b, c from test;
commit;
(Вы можете просто использовать отрицательный знак, чтобы избежать нарушений первичного ключа. Идентификаторы почти всегда положительны, но обычно не существует правила, запрещающего им быть отрицательными.)
Этот код не просто флаг FAST = TRUE. Есть много важных предостережений, которые вы должны понять в первую очередь.
Для параллелизма требуется Enterprise Edition (самая дорогая версия), не страшное аппаратное обеспечение (более одного ядра и один диск) и разумная конфигурация (если Администратор базы данных установит параметр parallel_max_servers = 1, тогда параллельные потоки не будут доступны). А параллелизм часто может «украсть» у других процессов - вам может понадобиться 10-кратное увеличение системных ресурсов только для 5-кратного повышения производительности. И получить правильную степень параллелизма может быть непросто.
Прямая запись записывается непосредственно в файлы данных и позволяет избежать записи REDO и UNDO (дополнительные данные используются для восстановления и согласованности). Компромисс здесь заключается в том, что оператор заблокирует всю таблицу - никто другой не сможет писать в нее одновременно. И таблица не будет восстановлена до следующего полного резервного копирования. И есть много вещей, которые могут блокировать прямые записи, такие как TRIGGERS, определенные отношения с внешним ключом и т. Д. c.
Внимательно проверьте план выполнения, чтобы убедиться, что вы получаете все функции. Вы хотите видеть «LOAD AS SELECT» вместо «LOAD CONVENTIONAL», чтобы гарантировать, что вы получаете прямую запись. И вы захотите увидеть операции «PX», чтобы убедиться, что вы получаете параллелизм. Вам понадобится «PX» над чтением и записывающей частью операции. Внимательно проверяйте раздел «Примечания», он может объяснить, почему вы не получаете то, о чем просите.
explain plan for
insert /*+ append parallel */ into test1
select * from test2;
select * from table(dbms_xplan.display);
Plan hash value: 1209398148
----------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
----------------------------------------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 1 | 39 | 2 (0)| 00:00:01 | | | |
| 1 | PX COORDINATOR | | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10000 | 1 | 39 | 2 (0)| 00:00:01 | Q1,00 | P->S | QC (RAND) |
| 3 | LOAD AS SELECT (HYBRID TSM/HWMB)| TEST1 | | | | | Q1,00 | PCWP | |
| 4 | OPTIMIZER STATISTICS GATHERING | | 1 | 39 | 2 (0)| 00:00:01 | Q1,00 | PCWP | |
| 5 | PX BLOCK ITERATOR | | 1 | 39 | 2 (0)| 00:00:01 | Q1,00 | PCWC | |
| 6 | TABLE ACCESS FULL | TEST1 | 1 | 39 | 2 (0)| 00:00:01 | Q1,00 | PCWP | |
----------------------------------------------------------------------------------------------------------------------------
Note
-----
- automatic DOP: Computed Degree of Parallelism is 2
Это может быть много работы! Вы можете потратить часы на оптимизацию одной INSERT, и вам может понадобиться прочитать документацию Oracle, чтобы решить некоторые проблемы. Но если вы терпеливы и у вас правильная конфигурация, вы можете увидеть огромные улучшения в производительности INSERT.