Я вижу некоторые существенные различия в производительности между OracleBulkCopy (ODP.NET) и SQL * Loader, когда сервер Oracle находится на другом компьютере.
У меня есть очень простая таблица в Oracle с тремя столбцами (один BINARY_FLOAT, два NUMBER (18,0)). Здесь нет первичных ключей, индексов, триггеров и т. Д. Он используется как промежуточная таблица для получения массовых данных в БД.
Загрузчику SQL * Loader требуется около 27 секунд, чтобы загрузить в таблицу 4,5 миллиона строк.
OracleBulkCopy загружает всего 1 миллион строк примерно за 10 минут.
OracleBulkCopy, согласно документации, * "... использует подход загрузки прямого пути, который похож, но не такой же, как Oracle SQL * Loader." * Его может не быть там с SQL * Loader в с точки зрения производительности, но эта разница просто смешная.
После базового анализа сетевого трафика я обнаружил, что OracleBulkCopy отправляет и принимает огромное количество небольших пакетов. Я использовал Wireshark для сравнения пакетов для каждого и нашел некоторые интересные результаты.
Загрузчик SQL * - после первоначального подтверждения соединения - отправляет серию 8-килобайтных пакетов (протокол TNS) и получает в ответ 60-байтовых ACK .
OracleBulkCopy отправляет серию 102-байтовых пакетов (протокол TNS) и получает в ответ 133-байтовый пакет (протокол TNS). Что за...!? Это похоже на отправку одной строки за раз!
В классе OracleBulkCopy я использую размер пакета 100 000 и использую специальный IDataReader для чтения из файла данных.
Итак, у меня следующие вопросы:
Кто-нибудь когда-нибудь видел такое поведение?
Действительно ли OracleBulkCopy работает как инструмент массовой загрузки?
Есть ли что-то, что мне нужно настроить, чтобы заставить его работать должным образом? (настройки клиент / сервер и т. д.)
Любая помощь приветствуется.