2010-05-04 3 views
10

Проблема заключается в том, что у нас есть огромное количество записей (более миллиона), которые нужно вставить в одну таблицу из приложения Java. Записи создаются кодом Java, это не переход из другой таблицы, поэтому INSERT/SELECT не поможет.Самый быстрый способ вставки очень большого количества записей в таблицу в SQL

В настоящее время мое узкое место является заявлением INSERT. Я использую PreparedStatement для ускорения процесса, но я не могу получить более 50 повторений в секунду на обычном сервере. Таблица не сложна вообще, и на ней нет указателей.

Процесс занимает слишком много времени, и время, затрачиваемое на него, будет иметь проблемы.

Что можно сделать, чтобы получить максимальную скорость (INSERT в секунду)?

База данных: MS SQL 2008. Приложение: на основе Java, с использованием драйвера JDBC от Microsoft.

ответ

6

Используйте BULK INSERT - он рассчитан на то, что вы просите, и значительно увеличивает скорость вставки.

Кроме того, (на всякий случай, если у вас действительно нет указателей), вы также можете рассмотреть , добавив индексы - некоторые индексы (большинство индексов по первому ключу) могут улучшить производительность вставок.

Фактическая скорость, с которой вы сможете вставлять записи, будет зависеть от точных данных, структуры таблицы, а также от аппаратного обеспечения/конфигурации самого SQL-сервера, поэтому я не могу дать вам никаких чисел.

+0

На самом деле у меня есть один индекс на ПК, который кластер, и данные вставляются в порядок PK, поэтому я не думаю, что это будет иметь какой-то эффект. Я буду пытаться BULK INSERT, я думаю, это мое решение. – Iravanchi

2

Вы изучали массовые операции bulk operations?

+0

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

10

Пакетные вставки. То есть, отправляйте только по 1000 строк за раз, а не по одной строке за раз, так что вы значительно сокращаете круглые поездки/серверные звонки

Performing Batch Operations на MSDN для драйвера JDBC. Это самый простой способ без реинжиниринга использовать оригинальные массовые методы.

Каждая вставка должна быть проанализирована и скомпилирована и выполнена. Партия будет означать намного меньше разборе/компиляции, так как 1000 (например) вставки будут собраны в один присест

Есть более эффективные способы, но это работает, если вы ограничены в сгенерированные вставок

+0

Я думаю, что кругооборот - очень небольшая часть задержки, потому что с 50 транзакциями в секунду для каждого запроса требуется 20 мс. Круглое путешествие меньше 1 мс. Я сделал другие оптимизации, чтобы удалить круглые поездки, но они мало помогли. Если пакетная обработка INSERT не приведет к большей эффективности внутренней обработки SQL. Имеет ли это? – Iravanchi

+0

@Irchi: Каждая вставка должна быть проанализирована, скомпилирована и выполнена. Партия будет означать намного меньше разбора/компиляции, потому что 1000 (например) вставках будут скомпилированы за один раз – gbn

+0

@Irchi: я бы попробовал это раньше, чтобы перестроить код для нас подход BCP – gbn

0

Посмотрите в Sql Server's bcp utility.

Это означало бы значительное изменение вашего подхода в том, что вы будете генерировать файл с разделителями и использовать внешнюю утилиту для импорта данных. Но это самый быстрый способ вставки большого количества записей в базу данных Sql Server db и ускорит ваше время загрузки на много порядков.

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

+0

Я предполагаю, что BULK INSERT использует BCP внутренне. Я прав? – Iravanchi

1

Вы считаете, что используете batch updates?

+0

Спасибо, я думаю, это тоже может быть полезно. Но я сначала попробую BULK INSERT, это кажется более перспективным! – Iravanchi

0

Я бы рекомендовал использовать для этого двигатель ETL. Вы можете использовать Pentaho. Это бесплатно.Двигатели ETL оптимизированы для выполнения массовой загрузки данных, а также любых форм преобразования/валидации, которые требуются.

1

Есть ли ограничение целостности или триггер на столе? Если это так, то вытащить его перед вставками поможет, но вы должны быть уверены, что можете позволить себе последствия.

+0

Хорошая точка, триггеры не помогают – gbn

+0

Есть два ограничения FK, я планировал их удалить и попробовать. Но BULK INSERT имеет возможность игнорировать ограничения, поэтому, полагаю, используя BULK INSERT, у меня будут все преимущества, которые мне нужны. – Iravanchi

Смежные вопросы