2013-08-06 3 views
4

У меня есть приложение, которое работает медленно через WAN - мы считаем, что причиной является множество вставк в таблицу. В настоящее время я изучаю более эффективные способы вставки нескольких строк одновременно.Oracle 11g - самый эффективный способ вставки нескольких строк

Я нашел этот метод:

INSERT ALL 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (100,20) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (21,2) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (321,10) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (22,13) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (14,121) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (11,112) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (112,23) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (132,2323) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (121,34) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (24333,333) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (1232,3434) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (4554,3434) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (3434,211) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (3434,1233) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (12,22) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (356,233) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (9347,23) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (8904,245) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (342,4545) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (453,233) 
SELECT 1 FROM DUAL; 

То, что я хотел бы знать: это метод выше на самом деле более эффективно, чем просто делает 20 "INSERT INTO MY_TABLE (1,1);"? Существуют ли другие способы сделать это?

+0

Есть ли триггеры на столе? – Harshit

+0

Hi Harshit - Нет, на столе нет триггеров – user1578653

+0

Предположительно, ваш реальный случай использования - более 20 строк? И не жестко закодированные значения? – APC

ответ

0

Некоторые СУБД, такие как MySQL и в настоящее время SQL Server поддерживает несколько строк вставить синтаксис данных:

Insert into myTable (c1, c2) values 
(1,1), 
(1,2), 
... ; 

(Более подробно в Inserting multiple rows of data of Sql Server или inserting multirow on mysql)

Но не оракул. Извините за плохие новости. Более близкий путь документирован на Tech on the Net.

2

Вы можете попробовать direct path insert для ускорения работы, но для 100 записей обычная вставка пути должна быть достаточно быстрой, и кажется, что проблема связана с блокировкой таблицы при вставке в журнал из большого количества источников.

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

insert /*+ APPEND */ 
into multi_insert(val_1, val_2) 
select * from (
    select 100, 20 from dual union all 
    select 21,  2 from dual union all 
    select 321, 10 from dual union all 
    select 22,  13 from dual union all 
    select 14, 121 from dual union all 
    select 11, 112 from dual union all 
    select 112, 23 from dual union all 
    select 132, 2323 from dual union all 
    select 121, 34 from dual union all 
    select 24333, 333 from dual union all 
    select 1232, 3434 from dual union all 
    select 4554, 3434 from dual union all 
    select 3434, 211 from dual union all 
    select 3434, 1233 from dual union all 
    select 12,  22 from dual union all 
    select 356, 233 from dual union all 
    select 9347, 23 from dual union all 
    select 8904, 245 from dual union all 
    select 342, 4545 from dual union all 
    select 453, 233 from dual 
) 

Если вставить заявление возникло из PL кода/SQL, то вы можете использовать массовую вставку с ForAll заявлением для повышения производительности (SQLFiddle):

declare 
    type TRowList is table of multi_insert%rowtype index by binary_integer; 

    vRowList TRowList; 
    vRow  multi_insert%rowtype; 
begin 


    vRow.val_1 := 100; 
    vRow.val_2 := 20; 
    vRowList(0) := vRow; 

    vRow.val_1 := 21; 
    vRow.val_2 := 2; 
    vRowList(1) := vRow; 

    vRow.val_1 := 321; 
    vRow.val_2 := 10; 
    vRowList(2) := vRow; 

    -- ... 

    forall vIdx in vRowList.first .. vRowList.last 
     insert /*+ APPEND_VALUES */ -- direct path insert 
     into multi_insert values vRowList(vIdx); 

end; 
2

«клиент сообщил, что он прекрасно работает когда приложение и Oracle находились в одной и той же локальной сети, но когда они переместили свои серверы Oracle за границу, они говорят, что программа выполняет очень медленно «

Хорошо, так что теперь мы куда-то попадаем. Если у вас есть настройка, в которой ваши сотни операторов являются отдельными вызовами, они, вероятно, будут отправляться в отдельных пакетах. Это было бы болезненно в глобальной сети по сравнению с локальной сетью. В этом случае было бы интересно увидеть, будет ли преобразование операторов из RBAR в нечто, основанное на наборе, уменьшит количество передаваемых пакетов.

Тем не менее, я все же советую вам получить некоторые факты, прежде чем вы начнете изменение. Разве у вашего клиента нет сетевого администратора, с которым вы могли бы поговорить? Или, по крайней мере, вы могли бы заставить их установить Wireshark и отправить вам несколько отчетов?

+0

Нам просто удалось настроить удаленный сервер Oracle на VPS и подключить к нему наше приложение. Я сделал захват wirehark и обнаружил, что он отправляет отдельные пакеты для каждой строки. Один из моих коллег перекомпилировал приложение, на этот раз используя некоторую функцию Direct Oracle Access (библиотека, которую мы используем для связи с Oracle) под названием «массив DML». Это почти не передает никаких пакетов и почти мгновенно. Тем не менее, я хотел бы знать, что такое «массив DML» на самом деле, поскольку у нас есть другие (не Delphi) приложения, которые могут постичь ту же проблему - можете ли вы пролить свет на это? – user1578653

+0

Вероятно, DOA использует некоторую вариацию подсказки [APPEND_VALUES] (http://docs.oracle.com/cd/E11882_01/server.112/e17118/sql_elements006.htm#SQLRF51109) с OCI и связывает параметры массива с инструкцией 'insert'. – ThinkJet

+1

AnyDac help имеет [объяснение] (http://www.da-soft.com/anydac/docu/frames.html?frmname=topic&frmfile=Array_DML.html) о теме и [здесь] (http: // docs. oracle.com/cd/B28359_01/appdev.111/b28395/oci05bnd.htm#sthref584) - это немного информация из документов Oracle. – ThinkJet

Смежные вопросы