Инструкция Oracle multi insert

в моем приложении я должен добавить много записей. Я использую следующую конструкцию:

   INSERT /*+ append parallel(t1, 4) parallel(t2, 4) */ ALL
   INTO t1 (col1, col2, col3) VALUES ('val1_1', 'val1_2', 'val1_3')
   INTO t2 (col1, col2, col3) VALUES ('val2_1', 'val2_2', 'val2_3')
   INTO t2 (col1, col2, col3) VALUES ('val3_1', 'val3_2', 'val3_3')
   .
   .
   .
SELECT 1 FROM DUAL;

Я также использую добавление и параллельные подсказки. Обратите внимание, что я вставляю данные в две разные таблицы. Кажется, что параллель игнорируется (мне сказал DBA). Так как я могу знать, используется он или нет? Можно ли использовать параллельную подсказку в такой конструкции? Это эффективно?

4 ответов


Это, вероятно, будет достаточно, чтобы заставить его работать:

alter session enable parallel dml;

вы можете проверить фактическую степень параллелизма с помощью такого запроса:

select px_servers_executions, v$sql.*
from v$sql where lower(sql_text) like '%insert%parallel%' order by last_load_time desc;

Если вы все еще не получаете параллельность есть много возможных причин. Для начала рассмотрим следующие параметры:

select * from v$parameter where name like 'parallel%'

но вы, вероятно, не хотите параллелизма для своего оператора insert. Параллелизм имеет большой объем накладных расходов и, как правило, полезен, только если вы имеете дело со многими тысячи или миллионы записей.

Я предполагаю, что ваша реальная проблема-это время для анализа большого оператора SQL. Вставки Multi-таблицы особенно плохи. Если вы попытаетесь вставить более нескольких сотен строк, ваш запрос займет много секунд для синтаксического анализа. И в зависимости от версии Oracle, он будет просто висеть вечно, если вы попытаетесь использовать 501 таблицы. Гораздо быстрее запустить несколько меньших запросов вместо одного большого запроса. Например, 5 вставок из 100 строк будут работать намного быстрее чем одна вставка 500 строк. (В общем, это полная противоположность как настроить производительность для Oracle. Это особый случай из-за ошибок, связанных с разбором больших операторов SQL.)


на добавить подсказку поддерживается только синтаксисом подзапроса инструкции INSERT, а не предложением VALUES. Если вы укажете подсказку APPEND с предложением VALUES, она будет проигнорирована и будет использоваться обычная вставка. Чтобы использовать вставку прямого пути с предложением VALUES, обратитесь к"подсказке APPEND_VALUES".


есть случаи, когда параллелизм отключен. В том числе, от документация Oracle:

параллелизм отключен для DML операции над таблицами, на которых определение триггера или ссылки ограничение целостности.

что кажется мне довольно большим ограничением. У вас есть триггер или внешний ключ на ваших столах?


включение параллелизма для 30 записей было бы пустой тратой ресурсов. Параллелизм предполагает дорогостоящие накладные расходы (разделение работы, назначение процессов, синхронизация результатов...) это не стоило бы затрат на такую небольшую операцию.

Я полагаю, вы выполняете этот оператор миллионы раз, если хотите оптимизировать его так плохо. В этом случае было бы, вероятно, более эффективно найти способ превратить эти миллионы операторов в Большие операции набора-это могло бы хорошо выгода от параллелизма.


обновление: другой идеей может быть запуск операторов с более чем одним сеансом, эффективно реализуя параллелизм DIY. Можете ли вы спроектировать свой процесс так, чтобы несколько сеансов одновременно считывали входные данные и вставляли их?