Самый быстрый способ делать ВСТАВКИ с использованием IBATIS - PullRequest
4 голосов
/ 13 ноября 2008

Мне нужно вставить 20 000 строк в одну таблицу (SQL Server 2005) с помощью iBatis Какой самый быстрый способ сделать это? Я уже использую пакетный режим, но он мало помог:

try {
  sqlMap.startTransaction();
  sqlMap.startBatch();
  // ... execute statements in between
  sqlMap.commitTransaction();
} finally {
  sqlMap.endTransaction();
}

Ответы [ 4 ]

4 голосов
/ 14 ноября 2008

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

Во-первых, вы не должны использовать какой-либо уровень абстракции, который вы используете, в данном случае iBatis, поскольку он эффективно предложит вам небольшую ценность, но этот уровень абстракции будет иметь некоторую (не обязательно большую, но некоторую) стоимость ЦП , Вы действительно должны просто использовать необработанное соединение с базой данных.

Далее вы отправите в кучу операторов INSERT. Вопрос заключается в том, следует ли вам использовать для строки простую строку (например, INSERT INTO TABLE1 VALUES ('x', 'y', 12)) против подготовленного оператора (INSERT INTO TABLE1 VALUES (?,?,?)).

Это будет зависеть от вашей базы данных и драйверов БД.

Проблема с использованием простой строки, в основном, заключается в стоимости преобразования из внутреннего формата (при условии, что вы вставляете данные Java) в строку. Преобразование числа или даты в строку на самом деле является довольно дорогой операцией процессора. Некоторые базы данных и драйверы будут работать с двоичными данными напрямую, а не просто со строковыми данными. Таким образом, в этом случае PreparedStatement может принести некоторую экономию ЦП, потенциально не требуя преобразования данных.

Недостатком является то, что этот фактор будет варьироваться в зависимости от поставщика БД и, возможно, даже от поставщика JDBC. Например, Postgres (я полагаю) работает только со строками SQL, а не с двоичными данными, поэтому использование PreparedStatement - пустая трата времени на простое построение строки самостоятельно.

Затем, когда у вас есть тип оператора, вы хотите использовать метод addBatch () класса операторов JDBC. Что addBatch делает, так это группирует операторы SQL в пакетном режиме. Преимущество заключается в том, что вместо отправки нескольких запросов в БД вы отправляете один запрос LARGE. Это сокращает сетевой трафик и дает заметный прирост пропускной способности.

Суть в том, что не все драйверы / базы данных поддерживают addBatch (по крайней мере, не очень хорошо), но и размер вашего пакета ограничен. Скорее всего, вы не можете добавить пакет для всех 20 000 строк и ожидать, что он будет работать, хотя это было бы лучшим выбором. Этот предел также может варьироваться в зависимости от базы данных.

Для Oracle в прошлом я использовал буфер 64K. По сути, я написал функцию-обертку, которая будет принимать буквальный оператор INSERT и накапливать их в пакетах по 64 КБ.

Итак, если вы хотите выполнить массовую вставку данных через SQL через JDBC, это способы сделать это. Большим улучшением является пакетный режим, оператор Statement против PreparedStatement больше предназначен для потенциальной экономии некоторого ЦП и, возможно, сетевого трафика, если ваш драйвер поддерживает двоичный протокол.

Тестируйте, ополаскивайте и повторяйте, пока вы не будете достаточно счастливы.

2 голосов
/ 14 ноября 2008

Хотя это не относится к вашему db-серверу, ранее я успешно записывал строки в локальный файл в формате csv и затем импортировал файл из базы данных. Это было значительно быстрее, чем операторы вставки или даже пакетная вставка.

2 голосов
/ 14 ноября 2008

В SQL Server быстрый способ вставки записей в пакетном режиме использует BULK INSERT . Однако этот метод загружает записи из текстового файла, а не непосредственно из вашего приложения.

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

Единственное, что вы можете попробовать, это вставить (подготовить) пакет в совершенно другую таблицу (без индексов или чего-либо еще). Затем переместите запись из этой промежуточной таблицы в целевую таблицу и удалите промежуточную таблицу. Это сначала переместит данные на сервер, так что окончательная вставка может произойти с самим сервером sql. Но опять же: это двухэтапный процесс, поэтому вам нужно посчитать время для обоих этапов.

1 голос
/ 14 ноября 2008

Массовая вставка лучше всего выполняется с использованием собственных инструментов массовой загрузки базы данных. Для Oracle это, например, SQL * Loader. Часто это быстрее, чем что-либо, что вы могли бы написать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...