Когда индексы должны быть удалены и воссозданы?

9

Мы строим хранилище данных, которое изначально будет 1 ТБ и будет расти около 20 гигабайт каждый месяц.

Для определенных таблиц мы выполняем ежедневные процессы ETL, а для других - еженедельно / ежемесячно.

Нужно ли удалять и воссоздавать индексы при импорте данных в таблицу?

Есть ли смысл отбрасывать и воссоздавать индексы или они автоматически обновляются?

Статистика настроена на автоматическое обновление.

Большое спасибо за вашу помощь и руководство.

Я получил этот гениальный сценарий:

SELECT 'ALTER INDEX [' + ix.name + '] ON [' + s.name + '].[' + t.name + '] ' +
       CASE WHEN ps.avg_fragmentation_in_percent > 40 THEN 'REBUILD' ELSE 'REORGANIZE' END +
       CASE WHEN pc.partition_count > 1 THEN ' PARTITION = ' + cast(ps.partition_number as nvarchar(max)) ELSE '' END
FROM   sys.indexes AS ix INNER JOIN sys.tables t
           ON t.object_id = ix.object_id
       INNER JOIN sys.schemas s
           ON t.schema_id = s.schema_id
       INNER JOIN (SELECT object_id, index_id, avg_fragmentation_in_percent, partition_number
                   FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, NULL)) ps
           ON t.object_id = ps.object_id AND ix.index_id = ps.index_id
       INNER JOIN (SELECT object_id, index_id, COUNT(DISTINCT partition_number) AS partition_count
                   FROM sys.partitions
                   GROUP BY object_id, index_id) pc
           ON t.object_id = pc.object_id AND ix.index_id = pc.index_id
WHERE  ps.avg_fragmentation_in_percent > 10 AND
       ix.name IS NOT NULL

отсюда:

http://weblogs.asp.net/okloeten/archive/2009/01/05/6819737.aspx

Вы предлагаете мне запускать этот скрипт ежедневно и на основании полученных результатов запускать сгенерированный код?

л --''''''--------- «» «» «» «» «» «»
источник
я был бы очень признателен, если бы кто-нибудь объяснил мне, в чем проблема с моим вопросом
l - '' '''--------- '' '' '' '' '' ''
Вот связанный вопрос, который я задал. dba.stackexchange.com/questions/11389/… Знания, которые я получил от этого вопроса, и ответы на них многому научили меня, и благодаря этому мы достигли больших успехов.
swasheck

Ответы:

13

Если это циклический ETL, и вы находитесь в среде данных разработки (т.е. НЕ ЖИВАЯ), то вам определенно следует управлять своими индексами как часть вашего цикла загрузки.

Я делаю это для нескольких наборов данных каждый месяц, самый большой из которых добавляет около 100 ГБ в месяц к набору данных 5 ТБ.

Я провел обширное тестирование, и из моего собственного опыта наиболее эффективный способ загрузки по индексам:

  1. DISABLE некластеризованные индексы, оставляя кластерный индекс без изменений
  2. Выполните загрузку raw в вашу таблицу данных
  3. REBUILD NC индексы

Если вы только периодически добавляете строки как часть управляемого ETL, это путь. Это также гарантирует, что вся ваша статистика актуальна.

Что касается статистики, важно отметить, что добавление 20 ГБ в базу данных объемом 1 ТБ не достигнет критической точки для автоматического обновления статистики, поэтому вы можете добавить данные за целый месяц, даже не обновляя статистику.

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

JNK
источник
4
Вы также можете обновить статистику как отдельную часть вашего процесса, смешанную между перестроениями NC, если делать это часто слишком дорого.
Аарон Бертран
1

Для базы данных объемом 1 ТБ + ежедневное удаление и создание индексов было бы излишним (даже если вы воссоздаете только некоторые из них).

Если вас беспокоит скорость вставки / обновления в таблицу из-за накладных расходов, добавляемых обновлениями индекса, то я рекомендую две вещи:

  1. Используйте суррогатные PK, чтобы вставки кластерного индекса имели минимальные издержки.
  2. Профилируйте свой DWH и создавайте некластеризованные индексы там, где это абсолютно необходимо.

Вам придется жить с обновлениями некластеризованного индекса во время операций вставки / обновления.

Если вас беспокоит фрагментация индекса, я рекомендую создавать ежедневные задания (задания агента SQL) для перестроения индексов. Период восстановления может быть любым, зависит от уровня фрагментации. Вы должны заметить это на практике и соответственно настроить график работы.

Вы можете добавить некоторую логику в сценарии перестроения, в зависимости от уровня фрагментации. Некоторые хорошие рекомендации вы можете найти здесь .

Суть в том, что ни при каких обстоятельствах не следует выполнять полное перестроение индекса для базы данных такого размера.

Марсель Н.
источник
6
Я должен не согласиться со многими из этого. Это будет зависеть от его варианта использования, но последняя строка under any circumstances you shouldn't do a full index rebuild on a database of that size.не совсем точна. Я выполняю ETL на очень больших базах данных в качестве своей основной служебной обязанности и вижу огромные преимущества от отключения и перестроения индексов.
JNK
1
Я хотел бы, чтобы это применимо и в моем случае. Для базы данных с объемом чуть более 1 ТБ, работающей в производственной среде, я едва могу позволить себе выполнять еженедельное перестроение некластеризованного индекса для нескольких таблиц с более чем 500 мил. строк. У меня есть несколько ETL-процессов, выполняемых каждую ночь, и последний шаг, который я делаю с 3:00, - это перестроение индексов.
Марсель Н.
0

Читайте о фрагментации

Вы хотите перестроить (не удалить / воссоздать) индексы, когда фрагментация слишком высокая

У меня есть процесс IndexOptimize в этом пакете, который должен запускаться каждую ночь.

Джереми Грей
источник