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

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

Ответ 1

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

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

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

Это не формула, а другая точка данных для вас.

Ответ 2

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

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

Для дальнейшей оптимизации операции SqlBulkCopy ознакомьтесь с советом MSDN; Я считаю, что использование SqlBulkCopyOptions.TableLock помогает сократить время загрузки.

Ответ 3

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

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

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

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

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

Ответ 4

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

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

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