Для чого рекомендований розмір партії SqlBulkCopy
? Я шукаю загальну формулу, яку можна використовувати як вихідну точку для налаштування продуктивності.
Для чого рекомендований розмір партії SqlBulkCopy
? Я шукаю загальну формулу, яку можна використовувати як вихідну точку для налаштування продуктивності.
Відповіді:
У мене є програма для імпорту, яка сидить на тому ж фізичному сервері, що і мій екземпляр SQL Server. Використовуючи спеціальний IDataReader
, він аналізує плоскі файли та вставляє їх у базу даних за допомогою SQLBulkCopy
. Типовий файл має близько 6 мільйонів кваліфікованих рядків, у середньому 5 стовпців десяткового та короткого тексту, близько 30 байт на рядок.
Враховуючи цей сценарій, я визнав, що пакетний пакет розміром 5000 є найкращим компромісом щодо швидкості та споживання пам'яті. Я почав з 500 і експериментував з більшими. Я виявив, що 5000 в 2,5 рази швидше, в середньому, ніж 500. Вставка 6 мільйонів рядків займає близько 30 секунд при розмірі партії 5000 і близько 80 секунд при розмірі партії 500.
10000 не було помірно швидшим. Переміщення до 50 000 покращило швидкість на кілька процентних пунктів, але не варто збільшувати навантаження на сервер. Понад 50000 не показали жодного покращення швидкості.
Це не формула, але для вас це ще одна точка даних.
Це питання, на яке я також витратив певний час. Я прагну оптимізувати імпорт великих файлів CSV (16+ ГБ, 65+ мільйонів записів та зростання) до бази даних SQL Server 2005 за допомогою консольної програми C # (.Net 2.0). Як Джеремі вже вже вказували , що вам потрібно буде зробити деякі тонке налаштування для ваших конкретних обставин, але я б порекомендував вам мати початковий розмір пакета 500 і контрольні значення вище і нижче цього.
Я отримав рекомендацію перевірити значення від 100 до 1000 для розміру партії з цього допису на форумі MSDN і був скептично налаштований. Але коли я тестував на розмір партії від 100 до 10000, я виявив, що 500 - це оптимальне значення для моєї заявки. 500 значення SqlBulkCopy.BatchSize
також рекомендується тут .
Щоб додатково оптимізувати свою роботу SqlBulkCopy, ознайомтеся з цією порадою MSDN ; Я вважаю, що використання SqlBulkCopyOptions.TableLock допомагає скоротити час завантаження.
Як зазначали інші, це залежить від вашого середовища, особливо від обсягу рядків та затримки мережі.
Особисто я б почав із встановлення BatchSize
властивості 1000 рядків і подивився, як це працює. Якщо це працює, я продовжую подвоювати кількість рядків (наприклад, до 2000, 4000 тощо), поки не отримаю тайм-аут.
В іншому випадку, якщо час очікування становить 1000, тоді я зменшую кількість рядків наполовину (наприклад, 500), поки не спрацює.
У кожному випадку я продовжую подвоювати (у разі успіху) або зменшувати вдвічі (у разі невдачі) різницю між кожним із двох останніх спроб розмірів партії, поки не знайду солодке місце.
Інший фактор, який слід врахувати, - це скільки часу потрібно для копіювання однієї партії рядків. Час очікування буде, якщо пакет копіюваних рядків перевищує BulkCopyTimeout
властивість, яке за замовчуванням становить 30 секунд. Ви можете спробувати подвоїти BulkCopyTimeout
властивість до 60 секунд. Це дозволяє довший проміжок часу копіювати більший набір пакетних рядків. Наприклад, партія з 50 000 рядків може зайняти близько 40 секунд, лише перевищуючи 30-секундний ліміт часу, тому навантаження на неї до 60 секунд може допомогти в продуктивності.
Все залежить від вашої реалізації.
На яку швидкість можна очікувати у вашій мережі? Чи використовуєте ви його у Forms або ASP.Net? Вам потрібно попередити користувача про хід? Який розмір загальної роботи?
На моєму досвіді запуск масової копії без вказаного розміру партії призведе до проблем із таймаутом. Мені подобається починати з чогось на кшталт 1000 записів і робити деякі корективи звідти.