Производительность массовой вставки в базу данных Oracle через OJDBC

У меня есть программа Java, которая используется для вставки большого количества (750 000) записей в базу данных Oracle. Я использую библиотеку OJDBC6 с клиентом OCI. Таблица для записи содержит 330 столбцов, 8 из которых присутствуют в одном или нескольких индексах.

Попробовав два подхода, я все еще борюсь с некоторыми проблемами производительности.

  1. Однократное создание подготовленного оператора, заполнение параметров для каждой записи и последующее выполнение оператора занимает 1 час 29 минут.
  2. Однократное создание готовой выписки, заполнение параметров для каждой записи, добавление их в батч и выполнение батча каждые 500/1000/5000 (перепробовал несколько вариантов) обработанных записей занимает 0ч27.

Однако, когда одни и те же данные сопоставляются с теми же таблицами с помощью инструмента ETL, такого как Informatica PowerCenter, это занимает всего пару минут. Я понимаю, что достижение этого тайминга может быть желаемым за действительное, но я сомневаюсь, что производительность не может быть достигнута.

Кто-нибудь имеет представление о разумных сроках для этого действия и как их можно достичь? Любая помощь приветствуется, большое спасибо заранее!

(Связанный с этим вопрос: мне также придется обновлять много записей. Какой подход будет наиболее эффективным: либо отслеживать измененные столбцы и создавать зависимый от записи подготовленный оператор, содержащий только эти столбцы, либо всегда обновлять все столбцы, тем самым повторно используя один и тот же подготовленный оператор?)


person Wouter    schedule 23.11.2012    source источник
comment
Вы можете вставить данные во временную таблицу unindex, из которой вы вставляете с помощью select. Если у вас одновременно есть только один писатель, вы можете использовать несколько потоков и использовать обычную таблицу в качестве промежуточной области. Вы также можете поэкспериментировать с параллельными пакетными вставками непосредственно в целевую таблицу, если вам не требуется, чтобы все было зафиксировано в одной транзакции.   -  person Sami Korhonen    schedule 23.11.2012
comment
Кстати, иметь таблицу с 330 столбцами обычно не очень хорошая идея.   -  person Sami Korhonen    schedule 23.11.2012
comment
Включена ли автоматическая фиксация? Не уверен, как это работает под капотом, но я могу предположить, что это немного замедлит работу.   -  person Alex Poole    schedule 23.11.2012
comment
Содержат ли некоторые из этих полей большие данные (blobs, clobs)? Это может вызвать проблемы. В прошлом я, используя пакетный API, вставлял 10 000 записей в минуту. Не по 330 столбцов, а 80/90 столбцов.   -  person Zagrev    schedule 24.11.2012
comment
Большое спасибо за ваш отзыв. @SamiKorhonen: макет таблицы подразумевается поставщиком внешнего инструмента. Мы ничего не можем с этим поделать, к сожалению. Я приму во внимание намек на параллель.   -  person Wouter    schedule 26.11.2012
comment
@AlexPoole: спасибо, это оказало некоторое влияние. Теперь поэкспериментируйте с интервалом фиксации, чтобы найти идеальный компромисс.   -  person Wouter    schedule 26.11.2012
comment
@Zagrev: нет больших данных. Только строки, даты и значения с плавающей запятой.   -  person Wouter    schedule 26.11.2012


Ответы (2)


Еще одна вещь, которую можно попробовать, - это удалить индексы, вставить данные, а затем перезагрузить индексы. Не так просто с Java, но достаточно просто.

person Zagrev    schedule 24.11.2012

Вы можете использовать ThreadGroup на Java http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/ThreadGroup.html

;)

person Rija Ramampiandra    schedule 11.12.2012