Каков рекомендуемый размер пакета для SqlBulkCopy?

87

Для чего рекомендуется размер партии SqlBulkCopy? Я ищу общую формулу, которую можно использовать в качестве отправной точки для настройки производительности.

Джонатан Аллен
источник

Ответы:

97

У меня есть утилита импорта, которая находится на том же физическом сервере, что и мой экземпляр SQL Server. Используя обычай IDataReader, он анализирует плоские файлы и вставляет их в базу данных с помощью SQLBulkCopy. Типичный файл имеет около 6 миллионов квалифицированных строк, в среднем 5 столбцов десятичного и короткого текста, около 30 байт на строку.

Учитывая этот сценарий, я обнаружил, что размер пакета в 5000 является лучшим компромиссом между скоростью и потреблением памяти. Я начал с 500 и экспериментировал с более крупными. Я обнаружил, что 5000 в среднем в 2,5 раза быстрее, чем 500. Вставка 6 миллионов строк занимает около 30 секунд при размере пакета 5000 и около 80 секунд при размере пакета 500.

10 000 были ненамного быстрее. Увеличение до 50 000 улучшило скорость на несколько процентных пунктов, но это не стоит увеличения нагрузки на сервер. Более 50 000 не показали улучшения скорости.

Это не формула, это еще одна точка данных, которую вы можете использовать.

Алрик
источник
3
Следует учитывать, что таблица пуста и имеет индексы. В этих случаях вы можете захотеть загрузить все одним пакетом, как указано здесь: technet.microsoft.com/en-us/library/ms177445(v=sql.105).aspx "Если вы массово импортируете данные в пустую таблицу с индексами и вы указываете размер пакета, таблица становится непустой после первого пакета. Начиная со второго пакета, данные полностью регистрируются. Для пустых индексированных таблиц рассмотрите возможность выполнения массового импорта в одном пакете ».
Sal
SqlBulkCopy передает данные из источника (например, DataTable) в Sql, так какая же «повышенная нагрузка на сервер» возникает при большом размере пакета? (например, 50,000)
BornToCode
29

Это проблема, над которой я тоже потратил некоторое время. Я хочу оптимизировать импорт больших файлов CSV (16+ ГБ, 65+ миллионов записей и их рост) в базу данных SQL Server 2005 с использованием консольного приложения C # (.Net 2.0). Как Джереми уже уже указывали , что вам нужно будет сделать некоторые тонкую настройку для ваших конкретных обстоятельств, но я бы порекомендовал вам иметь первоначальный размер пакета 500 и контрольные значения выше и ниже этого.

Я получил рекомендацию проверить значения от 100 до 1000 для размера пакета из этого сообщения на форуме MSDN и был настроен скептически. Но когда я проверил размер пакетов от 100 до 10 000, я обнаружил, что 500 было оптимальным значением для моего приложения. 500 значение SqlBulkCopy.BatchSizeтакже рекомендуется здесь .

Чтобы еще больше оптимизировать работу SqlBulkCopy, ознакомьтесь с этим советом MSDN ; Я считаю, что использование SqlBulkCopyOptions.TableLock помогает сократить время загрузки.

MagicAndi
источник
Я бы посчитал, что выполнение команды массового копирования на самом сервере, вероятно, будет быстрее.
Капитан Кенпачи
16

Как заявляли другие, это зависит от вашей среды, в частности от объема строки и задержки сети.

Лично я бы начал с установки BatchSizeсвойства на 1000 строк и посмотрел, как это работает. Если это сработает, я продолжаю удваивать количество строк (например, до 2000, 4000 и т. Д.), Пока не получу тайм-аут.

В противном случае, если тайм-аут наступает на 1000, я уменьшаю количество строк наполовину (например, 500), пока это не сработает.

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

Другой фактор, который следует учитывать, - это сколько времени нужно, чтобы скопировать один пакет строк. Тайм-ауты произойдут, если размер пакета копируемых строк превышает BulkCopyTimeoutсвойство, которое по умолчанию составляет 30 секунд. Вы можете попробовать удвоить BulkCopyTimeoutсвойство до 60 секунд. Это обеспечивает более длительный период времени для копирования большего набора строк пакета. Например, пакет из 50 000 строк может занять около 40 секунд, просто превышая 30-секундный лимит, поэтому увеличение его до 60 секунд может помочь в производительности.

Рэй
источник
4

Все зависит от вашей реализации.

Какую скорость вы можете ожидать в своей сети? Вы используете его в Forms или ASP.Net? Вам нужно предупреждать пользователя о прогрессе? Каков размер общей работы?

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

Джереми
источник
Скорость: варьируется, веб-формы: да, ASP.NET: да, широкие таблицы: да, узкие таблицы: да. Тысячи строк: да. Миллионы строк: да. Если вы можете придумать сценарий, я, вероятно, это сделаю.
Джонатан Аллен,
1
Тогда я должен придерживаться своего предыдущего ответа. Я не думаю, что есть серебряная пуля.
Джереми
-1

я пробовал несколько размеров, в моем случае 5000 было хорошо

Мустафа
источник