2008-11-13 10 views
4

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

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

ответ

1

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

2

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

+0

сделал тот же опыт с MySQL недавно: вставка данных с использованием простых инструкций INSERT INTO, загружаемых из файла, была значительно быстрее, чем выполнение пакетной вставки, как описано выше. – 2010-01-18 23:10:05

2

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

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

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

+1

+1 Массовая загрузка из файла. Написание плоского файла обычно удивительно быстро. – 2008-11-13 21:29:02

4

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

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

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

Это зависит от базы данных и драйверов DB.

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

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

Далее, если у вас есть тип оператора, вы хотите использовать метод addBatch() класса Statement JDBC. Что делает addBatch, так это группирование операторов SQL в, ну, пакет. Преимущество состоит в том, что вместо отправки нескольких запросов в БД вы отправляете один БОЛЬШОЙ запрос. Это сократит сетевой трафик и даст некоторые заметные выгоды в пропускной способности.

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

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

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

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