Як можна дослідити ефективність оператора BULK INSERT?


12

Я в основному .NET розробник, що використовує Entity Framework ORM. Однак, оскільки я не хочу зазнати невдачі у використанні ORM , я намагаюся зрозуміти, що відбувається всередині рівня даних (бази даних). В основному, під час розробки я запускаю профайлер і перевіряю, що деякі частини коду генерують за запитами.

Якщо я помітив щось надзвичайно складне (ORM може генерувати жахливі запити навіть із досить простих операторів LINQ, якщо вони не ретельно написані) та / або важких (тривалість, процесор, сторінка читає), я беру це в SSMS і перевіряю його план виконання.

Це добре працює для мого рівня знань у базі даних. Однак BULK INSERT здається особливою істотою, оскільки , схоже , це не створює SHOWPLAN .

Спробую проілюструвати дуже простий приклад:

Визначення таблиці

CREATE TABLE dbo.ImportingSystemFileLoadInfo
(
    ImportingSystemFileLoadInfoId INT NOT NULL IDENTITY(1, 1) CONSTRAINT PK_ImportingSystemFileLoadInfo PRIMARY KEY CLUSTERED,
    EnvironmentId INT NOT NULL CONSTRAINT FK_ImportingSystemFileLoadInfo REFERENCES dbo.Environment,
    ImportingSystemId INT NOT NULL CONSTRAINT FK_ImportingSystemFileLoadInfo_ImportingSystem REFERENCES dbo.ImportingSystem,
    FileName NVARCHAR(64) NOT NULL,
FileImportTime DATETIME2 NOT NULL,
    CONSTRAINT UQ_ImportingSystemImportInfo_EnvXIs_TableName UNIQUE (EnvironmentId, ImportingSystemId, FileName, FileImportTime)
)

Примітка: в таблиці не визначені інші індекси

Об'ємна вставка (що я ловлю на профілері, одна партія)

insert bulk [dbo].[ImportingSystemFileLoadInfo] ([EnvironmentId] Int, [ImportingSystemId] Int, [FileName] NVarChar(64) COLLATE Latin1_General_CI_AS, [FileImportTime] DateTime2(7))

Метрики

  • Вставлено 695 елементів
  • ЦП = 31
  • Читає = 4271
  • Пише = 24
  • Тривалість = 154
  • Загальна кількість таблиць = 11500

Для мого додатка це нормально, хоча показання здаються досить великими (я знаю дуже мало про внутрішні сторінки SQL Server, тому я порівнюю з розміром сторінки 8K та невеликою інформацією про запис)

Питання: як я можу розслідувати, чи можна оптимізувати цю BULK INSERT? Або це не має ніякого сенсу, оскільки це, мабуть, найшвидший спосіб переслати великі дані з клієнтської програми на SQL Server?

Відповіді:


14

Наскільки я можу сказати, ви можете оптимізувати об'ємну вставку так само, як і звичайну вставку. Зазвичай план запитів для простої вставки не є надто інформативним, тому не турбуйтеся про відсутність плану. Я перегляну кілька способів оптимізації вставки, але більшість з них, ймовірно, не застосовуються до вставки, яку ви вказали у питанні. Однак вони можуть бути корисними, якщо в майбутньому вам потрібно буде завантажувати більшу кількість даних.

1. Вставте дані в порядку кластеризації клавіш

SQL Server часто сортує дані, перш ніж вставляти їх у таблицю з кластерним індексом. Для деяких таблиць та додатків ви можете покращити продуктивність, сортуючи дані у плоському файлі та повідомляючи SQL Server, що дані сортуються за ORDERаргументом BULK INSERT:

ЗАМОВЛЕННЯ ({стовпчик [ASC | DESC]} [, ... n])

Визначає спосіб сортування даних у файлі даних. Ефективність масового імпорту покращується, якщо дані, що імпортуються, сортуються відповідно до кластерного індексу на таблиці, якщо такі є.

Оскільки ви використовуєте IDENTITYстовпець як кластерний ключ, вам не потрібно про це турбуватися.

2. Використовуйте, TABLOCKякщо можливо

Якщо ви гарантовано матимете лише один сеанс, вставляючи дані у свою таблицю, ви можете вказати TABLOCKаргумент BULK INSERT. Це може зменшити суперечки щодо блокування та може призвести до мінімальної реєстрації в деяких сценаріях. Однак ви вставляєте в таблицю з кластерним індексом, яка вже містить дані, тому ви не отримаєте мінімальний журнал без прапора 610 сліду, про який згадується пізніше у цій відповіді.

Якщо TABLOCKце неможливо, оскільки ви не можете змінити код , не втрачається вся надія. Подумайте про використання sp_table_option:

EXEC [sys].[sp_tableoption]
    @TableNamePattern = N'dbo.BulkLoadTable' ,
    @OptionName = 'table lock on bulk load' , 
    @OptionValue = 'ON'

Інший варіант - включити прапор трассингу 715 .

3. Використовуйте відповідний розмір партії

Іноді ви зможете налаштувати вставки, змінивши розмір партії.

ROWS_PER_BATCH = рядки_per_batch

Позначає приблизну кількість рядків даних у файлі даних.

За замовчуванням всі дані у файлі даних надсилаються на сервер у вигляді однієї транзакції, а кількість рядків у партії невідомо оптимізатору запитів. Якщо ви вказали ROWS_PER_BATCH (зі значенням> 0), сервер використовує це значення для оптимізації операції масового імпорту. Значення, вказане для ROWS_PER_BATCH, має бути приблизно таким же, як і фактична кількість рядків. Для отримання інформації про міркування щодо ефективності див. "Зауваження" далі в цій темі.

Ось цитата з подальшої статті:

Якщо кількість сторінок, що підлягають розмиттю в одній партії, перевищує внутрішній поріг, може відбутися повне сканування буферного пулу, щоб визначити, які сторінки підлягають розмиттю, коли пакет розпочинається. Це повне сканування може пошкодити ефективність масового імпорту. Ймовірний випадок перевищення внутрішнього порогу відбувається, коли великий пул буфера поєднується з повільною підсистемою вводу / виводу. Щоб уникнути переповнення буфера на великих машинах, або не використовуйте підказку TABLOCK (яка видалить масові оптимізації) або використовуйте менший розмір партії (що зберігає масові оптимізації).

Оскільки комп'ютери різняться, радимо протестувати різні розміри партій із завантаженням даних, щоб з’ясувати, що найкраще підходить для вас.

Особисто я просто вставив би всі 695 рядків однією партією. Настроювання розміру партії може істотно змінитись, якщо вставляти багато даних.

4. Переконайтеся, що вам потрібен IDENTITYстовпець

Я нічого не знаю про вашу модель даних або вимоги, але не потрапляйте в пастку додавання IDENTITYстовпчика до кожної таблиці. У Аарона Бертран є стаття про це під назвою Шкідливі звички до удару: розміщуючи стовпець ІДЕНТИМЕТІЙНОСТІ на кожен стіл . Щоб було зрозуміло, я не кажу, що ви повинні видалити IDENTITYстовпець із цієї таблиці. Однак якщо ви визначите, що IDENTITYстовпець не потрібний, і видаліть його, це може покращити продуктивність вставки.

5. Вимкнути індекси або обмеження

Якщо ви завантажуєте велику кількість даних у таблицю порівняно з тим, що у вас вже є, можливо, буде швидше відключити індекси або обмеження перед завантаженням та включити їх після завантаження. Для великих обсягів даних SQL Server, як правило, більш неефективно будувати індекс відразу, замість того, як дані завантажуються в таблицю. Схоже, ви вставили 695 рядків у таблицю з 11500 рядками, тому я б не рекомендував цю техніку.

6. Розгляньте TF 610

Trace Flag 610 дозволяє мінімально входити в деякі додаткові сценарії. Для вашої таблиці з IDENTITYкластеризованим ключем ви отримуватимете мінімальний журнал для будь-яких нових сторінок даних, якщо ваша модель відновлення проста чи об’ємна. Я вважаю, що ця функція за замовчуванням не ввімкнена, оскільки може погіршити продуктивність у деяких системах. Вам потрібно буде ретельно перевірити, перш ніж увімкнути цей прапор слідів. Рекомендована посилання Microsoft як і раніше є Посібником з продуктивності завантаження даних

Вплив вводу / виводу мінімальної лісозаготівлі під прапором 610 сліду

Коли ви здійснюєте транзакцію масового завантаження, яка була мінімально зареєстрована, усі завантажені сторінки повинні бути видалені на диск до завершення фіксації. Будь-які розмиті сторінки, що не потрапили в результаті попередньої операції контрольної точки, можуть створити велику кількість випадкових вводу-виводу. Порівнюйте це з операцією з повністю зареєстрованим журналом, яка створює послідовний введення / вивід у записі журналу замість цього і не вимагає завантаження сторінок на диск на час фіксації.

Якщо ваш сценарій завантаження - це невеликі операції вставки на btrees, які не перетинають межі контрольної точки, і у вас є повільна система вводу / виводу, використання мінімальної реєстрації може фактично уповільнити швидкість вставки.

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

На закінчення, напевно, ви не можете багато що зробити, щоб настроїти своє BULK INSERT. Мене б не хвилювало число прочитаних, яке ви спостерігали зі своєю вставкою. SQL Server повідомляє про читання кожного разу, коли ви вставляєте дані. Розглянемо наступне дуже просто INSERT:

DROP TABLE IF EXISTS X_TABLE;

CREATE TABLE X_TABLE (
VAL VARCHAR(1000) NOT NULL
);

SET STATISTICS IO, TIME ON;

INSERT INTO X_TABLE WITH (TABLOCK)
SELECT REPLICATE('Z', 1000)
FROM dbo.GetNums(10000); -- generate 10000 rows

Вихід від SET STATISTICS IO, TIME ON:

Таблиця "X_TABLE". Кількість сканувань 0, логічне зчитування 11428

У мене є 11428 повідомлень про читання, але це неприйнятна інформація. Іноді кількість повідомлених зчитувань може бути зменшена за допомогою мінімальної реєстрації, але, звичайно, різницю неможливо перевести безпосередньо на збільшення продуктивності.


12

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

  1. Перевірка кишок: чи робить ваш брандмауер штатний, глибокий огляд пакетів? В Інтернеті про це ви не знайдете багато, але якщо ваші масові вставки приблизно в 10 разів повільніше, ніж вони повинні бути, швидше за все, у вас є пристрій безпеки, який здійснює глибокий огляд пакетів рівня 3–7 та перевіряє наявність «Generic SQL Injection Prevention ".

  2. Виміряйте розмір даних, які ви плануєте масово вставляти, у байтах, за партію. І перевірте, чи зберігаєте ви будь-які дані LOB, оскільки це окрема операція зі збору та запису сторінки.

    Кілька причин, чому ви повинні зробити це так:

    а. У AWS IOPS Elastic Block Storage розбивається на байти, а не на рядки.

    1. Див. Розділ Amazon EBS Volume Performance на примірниках Linux »Характеристики вводу / виводу та моніторинг для пояснення того, що таке підрозділ EBS IOPS
    2. Зокрема, обсяги SSD загального призначення (gp2) мають концепцію "Кредити вводу / виводу та ефективність розриву", і для важкої обробки ETL звичайним є вичерпання кредитів розривного балансу. Тривалість передачі даних вимірюється в байтах, а не у рядках SQL Server :)

    б. Незважаючи на те, що більшість бібліотек чи білих тестів тестують на основі кількості рядків, це дійсно кількість сторінок, які можна записати на це питання, і, щоб обчислити це, вам потрібно знати, скільки байтів на рядок та розмір сторінки (зазвичай 8 КБ , але завжди двічі перевіряйте, чи успадкували ви систему від когось іншого.)

    SELECT *
    FROM 
    sys.dm_db_index_physical_stats(DB_ID(),OBJECT_ID(N'YourTable'), NULL, NULL, 'DETAILED')

    Зверніть увагу на avg_record_size_in_bytes та page_count.

    c. Як пояснює Пол Уайт у https://sqlperformance.com/2019/05/sql-performance/minimal-logging-insert-select-heap , "Щоб увімкнути мінімальний журнал INSERT...SELECT, SQL Server повинен очікувати понад 250 рядків із загальним розміром принаймні однією мірою (8 сторінок). "

  3. Якщо у вас є індекси з обмеженнями перевірки або унікальні обмеження, використовуйте SET STATISTICS IO ONта SET STATISTICS TIME ON(або SQL Server Profiler або розширені події SQL Server) для збору інформації, наприклад, чи має ваша об'ємна вставка читання операцій з читання. Операції зчитування зумовлені тим, що двигун бази даних SQL Server гарантує, що обмеження цілісності проходять.

  4. Спробуйте створити тестову базу даних, де PRIMARYFILEGROUP встановлений на диску RAM. Це має бути трохи швидше, ніж SSD, але також усунути будь-які питання щодо того, чи може ваш RAID-контролер додавати накладні витрати. У 2018 році це не повинно, але створивши декілька диференціальних базових ліній на зразок цієї, ви зможете отримати загальне уявлення про те, скільки ваших витрат додається обладнання.

  5. Також покладіть вихідний файл на диск накопичувача.

    Якщо розмістити вихідний файл на накопичувачі оперативної пам’яті, виключаєте будь-які проблеми із суперечками, якщо ви читаєте вихідний файл з того самого диска, що увімкнено FILEGROUP сервера бази даних.

  6. Переконайтеся, що ви відформатували ваш жорсткий диск, використовуючи розширення 64KB.

  7. Використовуйте UserBenchmark.com та орієнтуйте свій SSD. Це буде:

    1. Додайте більше знань іншим прихильникам продуктивності щодо того, якої продуктивності очікувати від пристрою
    2. Допоможе розібратися, чи продуктивність вашого диска недооцінена однолітками з таким же точним диском
    3. Допоможе розібратися, чи продуктивність вашого диска недостатньо виконує інші диски цієї ж категорії (SSD, HDD тощо)
  8. Якщо ви телефонуєте "INSERT BULK" з C # через Entity Framework Extensions, тоді переконайтеся, що ви "розігріли" спочатку JIT та "викинули" перші кілька результатів.

  9. Спробуйте створити лічильники ефективності для вашої програми. За допомогою .NET ви можете використовувати benchmark.NET, і він автоматично профілізує купу основних показників. Потім ви можете поділити свої спроби профілера із спільнотою з відкритим кодом та побачити, чи люди, що працюють з іншим обладнанням, повідомляють про одні й ті самі показники (наприклад, з попереднього моменту про використання UserBenchmark.com для порівняння).

  10. Спробуйте використовувати названі труби та запустити їх як localhost.

  11. Якщо ви орієнтуєтесь на SQL Server та використовуєте .NET Core, подумайте про те, як запустити Linux із SQL Server Std Edition - це коштує менше долара на годину навіть для серйозного обладнання. Основна перевага спроби того ж коду з тим же обладнанням з іншою ОС полягає в тому, щоб перевірити, чи викликає проблеми TCP / IP стек ядра ОС.

  12. Використовуйте діагностичні запити SQL Server Glen Barry для вимірювання затримки диска для накопичувача FILEGROUP таблиці вашої бази даних.

    а. Обов’язково вимірюйте перед тестом і після тесту. "Перед вашим тестом" просто говорить про те, чи є у вас жахливі IO характеристики як базові.

    б. Для вимірювання "під час тестування" вам дійсно потрібно використовувати лічильники продуктивності PerfMon.

    Чому? Тому що більшість серверів баз даних використовують якесь сховище, приєднане до мережі (NAS). У хмарі, в AWS, Elastic Block Storage - це саме те. Вас може зв'язати IOPS вашого обсягу EBS / NAS.

  13. Скористайтеся інструментом для вимірювання статистики очікування. Монітор SQL Red Gate , аналізатор продуктивності бази даних SolarWinds або навіть діагностичні запити SQL Server Глена Баррі або запит статистики Пола Рандала .

    а. Найбільш поширеними типами очікування, ймовірно, будуть пам'ять / процесор, WRITELOG, PAGEIOLATCH_EX та ASYNC_NETWORK_IO .

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

  14. Виміряйте ефекти декількох одночасних INSERT BULKкоманд з TABLOCKвідключеними (TABLOCK, ймовірно, змусить серіалізацію команд INSERT BULK). Ваше вузьке місце може чекати INSERT BULKзавершення; вам слід спробувати поставити в чергу стільки таких завдань, скільки фізична модель даних сервера вашого сервера баз даних.

  15. Подумайте про розподіл таблиці. Як окремий приклад: якщо таблиця вашої бази даних додається лише для додавання, Ендрю Новік запропонував створити "СЬОГОДНІ" FILEGROUPта розділити її принаймні на дві групи файлів, СЬОГОДНІ та ПЕРЕДІ_ТОДАЙ. Таким чином, якщо ваші INSERT BULKдані є лише даними на сьогодні, ви можете відфільтрувати поле CreateOn, щоб змусити всі вставки вдарити по одній FILEGROUP, і тим самим зменшити блокування при використанні TABLOCK. Ця методика більш докладно описана у програмі Microsoft Whitepaper: Стратегії розподілених таблиць та індексів за допомогою SQL Server 2008

  16. Якщо ви використовуєте індекси для зберігання стовпців, вимкніть TABLOCKта завантажте дані у 102 400 рядків Пакетний розмір. Потім можна паралельно завантажувати всі свої дані безпосередньо в групи рядків стовпців. Ця пропозиція (і задокументована раціонально) походить від індексів Microsoft Columnstore - Інструкції щодо завантаження даних :

    Об'ємне завантаження має такі вбудовані оптимізації продуктивності:

    Паралельні навантаження: Ви можете мати кілька одночасних об'ємних навантажень (bcp або масових вставок), які кожен завантажує окремий файл даних. На відміну від масових навантажень rowstore в SQL Server, вам не потрібно вказувати, TABLOCKтому що кожен об'ємний імпортний імпорт завантажуватиме дані виключно в окремі групи рядків (стислі або дельтові групи рядків) з ексклюзивним блокуванням. Використання TABLOCKпризведе до виключного блокування на столі, і ви не зможете паралельно імпортувати дані.

    Мінімальний журнал:Об'ємне навантаження використовує мінімальну реєстрацію даних, що надходять безпосередньо до стислих груп рядків. Будь-які дані, що надходять до дельтової групи рядків, повністю реєструються. Сюди входять будь-які розміри партії, менші за 102 400 рядків. Однак при масовому завантаженні ціль більшості даних обходити групи дельтових рядів.

    Оптимізація блокування: Під час завантаження у стиснуту групу рядків набувається блокування X для групи рядків. Однак, коли масове завантаження в групу рядків дельти, X група отримується у групі рядків, але SQL Server все ще фіксує блоки PAGE / EXTENT, оскільки блокування X rowgroup не є частиною ієрархії блокування.

  17. Станом на SQL Server 2016 більше не потрібно включати прапор 610 сліду для мінімального входу в індексовану таблицю . Цитуючи інженера Майкрософт Парікшит Саджані ( акцент мій ):

    Однією з цілей дизайну SQL Server 2016 було покращити продуктивність та масштабованість двигуна поза коробкою, щоб він працював швидше, не вимагаючи жодних регуляторів чи прапорів слідів для клієнтів. В рамках цих удосконалень одним із удосконалень, внесених у код двигуна SQL Server, було включення контексту об'ємного навантаження (також його називають швидким вставками або контекстом швидкого навантаження) та мінімального журналу за замовчуванням при виконанні операцій масового навантаження в базі даних з простою або модель відновлення масової реєстрації. Якщо ви не знайомі з мінімальним веденням журналу, я б дуже рекомендував прочитати цю публікацію в блозі від Sunil Agrawal, де він пояснює, як працює мінімальна реєстрація в SQL Server. Для того, щоб масові вставки були мінімально введені, вони все ще повинні відповідати необхідним умовам, які тут задокументовані.

    В рамках цих удосконалень у SQL Server 2016 вам більше не потрібно вмикати прапор 610 сліду для мінімального входу в індексовану таблицюі він приєднується до деяких інших прапорів слідів (1118, 1117, 1236, 8048), щоб стати частиною історії. У SQL Server 2016, коли операція масового завантаження призводить до виділення нової сторінки, усі рядки, які послідовно заповнюють цю нову сторінку, мінімально реєструються, якщо всі інші попередні умови для мінімального ведення журналу, обговорені раніше. Рядки, вставлені на існуючі сторінки (не виділяється нова сторінка) для підтримки порядку індексу, все ще повністю реєструються, як і рядки, переміщені в результаті розбиття сторінки під час завантаження. Також важливо ввімкнути ALLOW_PAGE_LOCKS для індексів (що за замовчуванням увімкнено), щоб мінімальна операція ведення журналів працювала, оскільки блокування сторінок отримуються під час розподілу, і таким чином реєструються лише розміщення сторінок або обсягів.

  18. Якщо ви використовуєте SqlBulkCopy в C # або EntityFramework.Extensions (який використовує SqlBulkCopy під кришкою), то перевірте конфігурацію збірки. Ви проводите тести в режимі випуску? Чи встановлена ​​цільова архітектура на будь-який процесор / x64 / x86?

  19. Поміркуйте, використовуючи sp_who2, щоб дізнатись, чи УПРАВЛЕНО транзакцію INSERT BULK ЦІЛЬНО МОЖНА БУДУТЬСЯ, оскільки його заблокує інший павук. Розгляньте питання про те, як мінімізувати блокування SQL Server . Ви також можете використовувати sp_WhoIsActive Адама Маханіка, але sp_who2 дасть вам основну інформацію, яка вам потрібна.

  20. Можливо, у вас просто поганий диск вводу / виводу. Якщо ви робите об'ємну вставку і використання вашого диска не дає 100%, і вона застрягла близько 2%, то, ймовірно, у вас є погана прошивка або несправний пристрій вводу / виводу. (Це трапилося з моїм колегою.) Використовуйте [SSD UserBenchmark] для порівняння з іншими щодо продуктивності обладнання, особливо якщо ви можете повторити повільність на вашому локальному розробнику. (Я ставлю це останнє у списку, оскільки більшість компаній не дозволяють розробникам запускати бази даних на своєму локальному комп'ютері через ризик IP-адреси.)

  21. Якщо ваша таблиця використовує стиснення, ви можете спробувати запустити кілька сеансів, і в кожному сеансі почніть з використання наявної транзакції і запустіть це перед командою SqlBulkCopy:

    НАПРАВЛЕННЯ КОНФІГУРАЦІЇ СЛУЖБА ПРОЦЕСУ ПРОФЕСІЙНОСТІ CPU = AUTO;

  22. Для постійного завантаження один потік ідей, спершу викладених у документі Microsoft, Таблиці з розділеними таблицями та Стратегіями покажчиків за допомогою SQL Server 2008 :

    Постійне завантаження

    У сценарії OLTP нові дані можуть надходити постійно. Якщо користувачі також запитують останній розділ, безперервне вставлення даних може призвести до блокування: Запити користувачів можуть блокувати вставки, а також вставки можуть блокувати запити користувачів.

    Конфлікт у завантажувальній таблиці чи розділі може бути зменшений за допомогою знімків знімків, зокрема, READ COMMITTED SNAPSHOTрівня ізоляції. Під READ COMMITTED SNAPSHOTізоляцією вставки в таблицю не викликають активності в сховищі версій tempdb , тому накладні витрати tempdb мінімальні для вставок, але загальні блокування не будуть прийматися за запитами користувачів на одному розділі.

    В інших випадках, коли дані вставляються в таблицю з розділеною ділянкою постійно з високою швидкістю, ви, можливо, зможете поетапно ставити дані в таблиці, а потім повторно вставляти їх у найновіший розділ до тих пір, поки не з'явиться вікно для поточний розділ проходить і дані потім вставляються в наступний розділ. Наприклад, припустімо, що у вас по черзі є дві тактові таблиці, які по черзі отримують дані по 30 секунд: одна таблиця за першу половину хвилини, друга - друга половина хвилини. Процедура, що зберігається вставкою, визначає, в якій половині хвилини знаходиться поточна вставка, а потім вона вставляється в першу тактову таблицю. Коли 30 секунд закінчено, процедура вставки визначає, що вона повинна бути вставлена ​​у другу таблицю інсценізації. Потім інша збережена процедура завантажує дані з першої таблиці поетапних дій у найновіший розділ таблиці, а потім обрізає першу таблицю послідовності. Ще через 30 секунд ця сама збережена процедура вставляє дані з другої збереженої процедури і вводить їх у поточний розділ, а потім обрізає другу таблицю послідовності.

  23. Посібник з продуктивності завантаження даних команди команди Microsoft CAT

  24. Переконайтесь, що ваша статистика актуальна. Використовуйте FULLSCAN, якщо зможете після кожного побудови індексу.

  25. Налаштування продуктивності SAN за допомогою SQLIO, а також переконайтесь, що ви використовуєте механічні диски, щоб розділилися диски. Див. Кращі практики вирівнювання дискових розділів Microsoft .

  26. COLUMNSTORE INSERT/ UPDATEвиступ


2

Зчитування, ймовірно, будуть унікальними та обмеженнями FK, що перевіряються під час вставки - ви можете отримати покращення швидкості, якщо ви зможете їх відключити під час вставки та включити / відтворити їх згодом. Вам потрібно буде перевірити, чи це робить його загальнішим у порівнянні з тим, щоб підтримувати їх активними. Це також не може бути хорошою ідеєю, якщо інші процеси записуються в ту саму таблицю одночасно. - Гарет Ліон

Згідно із питаннями Q&A, зовнішні ключі стають ненадійними після масової вставки , обмеження FK стають недовіреними після опції BULK INSERTбез CHECK_CONSTRAINTSопції (мій випадок, коли я закінчився недовірливими обмеженнями). Це незрозуміло, але не було б сенсу перевіряти їх і все-таки робити їх недовіреними. Однак PK і UNIQUE все одно перевірятимуться (див. BULK INSERT (Transact-SQL) ). - Олексій

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