Підвищити швидкість відновлення індексу на SQL-сервері


9

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

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

Існує> 100 таблиць і майже 2000 індексів, які потрібно відновити. База даних має розмір 200 ГБ.

Ключовий розділ сценарію, який я виконую, такий:

declare c_toggle_index cursor FORWARD_ONLY READ_ONLY for
    select  'alter index ' + QUOTENAME(i.name) + ' on ' + o.name + ' rebuild'
    from    sys.indexes as i
    Inner Join sys.objects o
    On o.object_id = i.object_id
    Where o.is_ms_shipped = 0
    And i.index_id >= 1
    and i.type > 1
    and i.is_disabled = 1

Я розглядав настройку ONLINE = OFF для оператора alter index, але оскільки індекси починаються відключеними, я не був впевнений, що це налаштування матиме якийсь ефект. Я також розглядав налаштування SORT_IN_TEMPDB = ON, але оскільки файли tempdb знаходяться на тому ж диску, що і .mdf-файли баз даних, я припускав, що це також не має ніякої користі.

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

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


3
Коли ви говорите, що ваша проблема - це час імпорту, ви маєте на увазі час від початку імпорту до кінця повторного включення індексів? Якщо це так, вам слід просто залишити індекси, включені під час імпорту. 2000 індексів для даних 200 Гб мені здається безліччю індексів. Можливо, ви повинні подивитися на використання DMV з індексу, щоб побачити, чи є такі, які можна було б видалити.
Макс Вернон

1
Для уточнення, вам потрібно зробити той самий імпорт 200 Гб неодноразово, а не один раз?
Джон Сейгель

1
Мені потрібно імпортувати лише один раз, але як частину більшого процесу з обмеженим вікном часу, тому я зараз тестую цей процес, щоб він міг поміститися у цьому вікні. @MaxVernon Схоже, ти маєш рацію, що залишити індекси включеними - це найшвидший спосіб, хоча я здивований, бо читав, що зазвичай швидше відключати індекси, імпортувати дані, а потім знову включати індекси. Це стороння база даних, тому видалити індекси або змінити їх іншим способом насправді неможливо.
polH

3
Добре. Про CXPACKETочікування: індекс відновлює самі скануючі індекси (навіть індекс перебудовується ), і ці сканування можуть використовувати паралелізм. Ви не повинні турбуватися про ці очікування - паралелізм, мабуть, допомагає.
Джон Сейгель

Відповіді:


10

Для досягнення оптимальних показників імпорту в цьому сценарії потрібно три речі:

  1. Вставки з базового столу з мінімальними записами
  2. Некластеризований збір індексів з мінімальним журналом
  3. Уникання фізичних читань

Мінімальний журнал

Досягнення вкладених елементів із мінімальною реєстрацією в порожню кластеризовану таблицю без некластеризованих індексів вимагає:

  1. Використання або моделей відновлення бази даних, SIMPLEабоBULK_LOGGED
  2. Завдання блокування таблиці і упорядкований введення (наприклад , TABLOCKі ORDERпідказка)

Бічна примітка:

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

Якщо план запитів використовує окремий ітератор для некластеризованого індексу, а у ітератора встановлено DMLRequestSortвластивість true, некластеризовані вставки індексу будуть мінімально зафіксовані, за умови виконання інших згаданих раніше умов.

Побудова некластеризованих індексів окремо

Перевагами цього є:

  1. Кластеризовані індексні вставки можна мінімально реєструвати, не вмикаючи TF 610
  2. CREATE INDEX мінімально реєструється, якщо модель відновлення відсутня FULL

Уникання фізичних читань

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

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

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

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

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

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

Підсумок

Процес імпорту повинен бути перероблений для завантаження однієї таблиці за один раз. Це означає завантаження таблиці та створення всіх некластеризованих індексів перед переходом до наступного. Екземпляр SQL Server повинен мати достатньо пам’яті для того, щоб утримувати найбільшу таблицю і виконувати найбільший некластеризований сортування індексів одночасно.

Ви могли б також спробувати включити TF 610 перед завантаженням даних в таблиці з некластерізованний індексами вже на місці. Зазвичай це не так швидко, як попередній метод, але він може бути досить швидким.

Для отримання додаткової інформації див. Наступне:

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

Операції, які можна мінімально реєструвати

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