В некотором старом коде, который у меня есть, используется 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 ускорит работу (я еще не пробовал), но для этого потребуется слишком много изменений в ранее существовавших хранимых процедурах.
Да, ассоциативный массив 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, но вы должны это понять) –