Який рекомендований розмір партії для SqlBulkCopy?


87

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

Відповіді:


97

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

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

10000 не було помірно швидшим. Переміщення до 50 000 покращило швидкість на кілька процентних пунктів, але не варто збільшувати навантаження на сервер. Понад 50000 не показали жодного покращення швидкості.

Це не формула, але для вас це ще одна точка даних.


3
Одне слід врахувати, якщо таблиця порожня і має індекси. У цих випадках вам може знадобитися завантажити все одним пакетом, як зазначено тут: technet.microsoft.com/en-us/library/ms177445(v=sql.105).aspx "Якщо ви масово імпортуєте дані в порожню таблицю з індексами і ви вказуєте розмір партії, таблиця стає порожньою після першої партії. Починаючи з другої партії, дані повністю реєструються. Для порожніх індексованих таблиць розгляньте можливість масового імпортування в одній партії. "
Сал

SqlBulkCopy передає дані з джерела (наприклад, DataTable) в Sql, тож яке "збільшене навантаження на сервер" має він при великому розмірі партії? (наприклад, 50000)
BornToCode

29

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

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

Щоб додатково оптимізувати свою роботу SqlBulkCopy, ознайомтеся з цією порадою MSDN ; Я вважаю, що використання SqlBulkCopyOptions.TableLock допомагає скоротити час завантаження.


Я вважаю, що запуск команди масового копіювання на самому сервері, мабуть, буде швидшим.
Капітан Кенпачі

16

Як зазначали інші, це залежить від вашого середовища, особливо від обсягу рядків та затримки мережі.

Особисто я б почав із встановлення BatchSizeвластивості 1000 рядків і подивився, як це працює. Якщо це працює, я продовжую подвоювати кількість рядків (наприклад, до 2000, 4000 тощо), поки не отримаю тайм-аут.

В іншому випадку, якщо час очікування становить 1000, тоді я зменшую кількість рядків наполовину (наприклад, 500), поки не спрацює.

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

Інший фактор, який слід врахувати, - це скільки часу потрібно для копіювання однієї партії рядків. Час очікування буде, якщо пакет копіюваних рядків перевищує BulkCopyTimeoutвластивість, яке за замовчуванням становить 30 секунд. Ви можете спробувати подвоїти BulkCopyTimeoutвластивість до 60 секунд. Це дозволяє довший проміжок часу копіювати більший набір пакетних рядків. Наприклад, партія з 50 000 рядків може зайняти близько 40 секунд, лише перевищуючи 30-секундний ліміт часу, тому навантаження на неї до 60 секунд може допомогти в продуктивності.


4

Все залежить від вашої реалізації.

На яку швидкість можна очікувати у вашій мережі? Чи використовуєте ви його у Forms або ASP.Net? Вам потрібно попередити користувача про хід? Який розмір загальної роботи?

На моєму досвіді запуск масової копії без вказаного розміру партії призведе до проблем із таймаутом. Мені подобається починати з чогось на кшталт 1000 записів і робити деякі корективи звідти.


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

1
Тоді я повинен дотримуватися своєї попередньої відповіді. Я не думаю, що є срібна куля.
Джеремі

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.