2013-12-09 5 views
1

В некотором старом коде, который у меня есть, используется OracleDataAdaper.Update(DataSet). Если я вызываю тестовый сохраненный proc (который имеет только входные параметры), он занимает около 24 секунд для вставки 20 000 строк. Мне нужно было улучшить это, поэтому я переключился на использование привязки массива. При привязке массива ExecuteNonQuery() занимает менее 3 секунд, чтобы вставить те же 20 000 строк! Это огромное улучшение производительности, и я также избегаю создания дорогостоящих DataSet.Оценка привязки массива ODP.NET-массива/выходного параметра

Однако у меня возникли проблемы с хранимыми процедурами, которые имеют параметры или функции OUT, возвращающие значения.

Вставка тех же 20 000 строк через сохраненный процесс, который имеет параметр OUT с использованием OracleDataAdaper.Update(DataSet) занимает около 26 секунд - что на 2 секунды или на 8% медленнее, чем без параметра OUT - неплохо.
Но вызов такой же хранимой процедуры с использованием привязки массива вызывает ExecuteNonQuery() для запуска в течение 15 минут! Это на 300% медленнее, чем без параметра OUT!


Для всех OUT/IN OUT/параметры возвращения типа переменной длины (т.е. VARCHAR2), я установил OracleParameter.ArrayBindSize свойство int[numOfRows] со всеми значениями, установленными для максимального значения для типа (т.е. 4000 для VARCHAR2).

Мой тест ХП выглядит следующим образом (в реальной жизни, я мог бы возвращаться порядковым номером):

PROCEDURE INSERT_TEST(
     p_key   VARCHAR2, 
     p_id    NUMBER, 
     p_dt    DATE, 
     p_unique_key OUT VARCHAR2) 
     AS 
     BEGIN 
     INSERT INTO T_TEST_DAL(
         UNIQUE_KEY, 
         NUM_ID, 
         DT_VAL) 
     VALUES (
       p_key, 
       p_id, 
       p_dt) 
     RETURNING UNIQUE_KEY 
      INTO p_unique_key; 
    END INSERT_TEST; 

Я использую ODP.NET Oracle.DataAccess v4.112.3.0, но Я уверен, что это не зависит от версии.

Кто-нибудь сталкивался с подобными проблемами с параметрами OUT, связанными с массивом? Нужно ли мне устанавливать другое свойство для параметров OUT/Return, чтобы ускорить это?

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

+0

Да, ассоциативный массив PL/SQL ускоряет его. Посмотрите здесь пример: http://stackoverflow.com/questions/20401050/is-there-a-way-to-pass-a-set-of-values-as-a-parameter-in-an- oracle-sql-statement/20405447 # 20405447 (извините код VB.NET, но вы должны это понять) –

ответ

0

Оказывается, что ODP.NET не обеспечивает способ настройки «размера выборки» для ExecuteNonQuery() с привязкой к массиву. Поэтому, когда хранимый proc содержит параметр OUT (или функция имеет параметр RETURN), Oracle отправляет результаты каждого элемента обратно вызывающему абоненту отдельно. Это приводит к множеству сетевых издержек и значительно замедляет процесс.

При использовании OracleDataAdapter.Update(DataSet) результаты выполнения отправляются партиями, что приводит к снижению сетевых накладных расходов.

Когда нет параметров OUT, гораздо быстрее использовать ExecuteNonQuery(), а не OracleDataAdapter.Update(DataSet).

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