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