Отключить и повторно включить все индексы в базе данных SQL Server

Я запускаю DTS для выполнения задач в моей базе данных, в которых сначала мне нужно отключить индексы all в базе данных и снова включить их, когда DTS завершит свою работу.

Есть ли способ отключить все индексы во всей базе данных, а затем снова включить их?

Я знаю, как отключить/включить по одному, может ли кто-нибудь помочь мне с возможностью отключить/включить все сразу как шаг в DTS.

Ответы

Ответ 1

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

select 'ALTER INDEX [' + I.name + '] ON [' + T.name + '] DISABLE' 
from sys.indexes I
inner join sys.tables T on I.object_id = T.object_id
where I.type_desc = 'NONCLUSTERED'
and I.name is not null

Ответ 2

Это работает для SQL Server 2008 и более новых версий. Он позволяет использовать разные схемы, а также имена, в которых есть пробелы, тире и другие специальные символы, которые должны быть указаны. Что такое квадратные скобки [] в операциях sql?

Эти скрипты выводят код на вкладку результатов. Вы должны скопировать/вставить вкладку запроса и выполнить их.

Отключить script

SELECT 'ALTER INDEX ' + QUOTENAME(I.name) + ' ON ' +  QUOTENAME(SCHEMA_NAME(T.schema_id))+'.'+ QUOTENAME(T.name) + ' DISABLE' 
FROM sys.indexes I
INNER JOIN sys.tables T ON I.object_id = T.object_id
WHERE I.type_desc = 'NONCLUSTERED'
AND I.name IS NOT NULL
AND I.is_disabled = 0

Включить script (перестроить)

SELECT 'ALTER INDEX ' + QUOTENAME(I.name) + ' ON ' +  QUOTENAME(SCHEMA_NAME(T.schema_id))+'.'+ QUOTENAME(T.name) + ' REBUILD' 
FROM sys.indexes I
INNER JOIN sys.tables T ON I.object_id = T.object_id
WHERE I.type_desc = 'NONCLUSTERED'
AND I.name IS NOT NULL
AND I.is_disabled = 1

Это основано на другом ответе здесь.

Ответ 3

Мы можем использовать ниже скрипт для отключения индексов

ALTER INDEX ALL ON [TableName]
DISABLE;

Сделайте объемную вставку в таблицу, а не ниже script.

ALTER INDEX ALL ON [TableName]
REBUILD;

Ответ 4

Чтобы включить индекс, вы должны его перестроить. Этот script будет восстанавливать все отключенные индексы.

DECLARE @my_sql2 NVARCHAR(200);

DECLARE cur_rebuild CURSOR FOR 
   SELECT 'ALTER INDEX ' +  i.name + ' ON ' + t.name + ' REBUILD' FROM sys.indexes i JOIN sys.tables t ON i.object_id = t.object_id WHERE i.is_disabled = 1 ORDER BY t.name, i.name;
OPEN cur_rebuild;
FETCH NEXT FROM cur_rebuild INTO @my_sql2;
WHILE @@FETCH_STATUS = 0
   BEGIN
      EXECUTE sp_executesql  @my_sql2;
      FETCH NEXT FROM cur_rebuild INTO @my_sql2;
   END;
CLOSE cur_rebuild;
DEALLOCATE cur_rebuild;
GO

Ответ 5

Вам нужно будет запустить script, который будет выбирать метаданные для таблицы и индекса. Затем вы можете сделать следующее:

ALTER INDEX indexname ON tablename DISABLE; 

Позже вы можете запустить аналогичный script для восстановления:

ALTER INDEX indexname ON tablename REBUILD; 

Вы можете делать это за один раз или собирать их в переменную NVARCHAR (MAX) и выполнять их как одну партию. Вы можете увидеть пример кода в этом более раннем вопросе:

Отключить все некластеризованные индексы

Ответ 6

Отключение индексов - хорошая идея, когда дело доходит до загрузки большого количества данных, но... большая проблема - это кластеризованные индексы. Если вы отключите кластеризованный индекс, вы отключили всю таблицу.

Несколько вариантов предлагают сами, и ни один из них не прост.

1) Прокрутите системные представления (sys.indexes), извлеките имя таблицы и индекса, создайте и выполните динамический SQL, чтобы отключить индекс. У вас есть "отменить", чтобы повторно включить их. (Будьте осторожны - был ли он уникальным индексом или уникальным ограничением?) Это, увы, работает только в том случае, если вы не используете кластерные индексы. Удачи вам в этом.

2) Что касается 1, но пропустите любые кластерные индексы. Когда вы загружаете данные, убедитесь, что они загружаются в (кластерный индекс) последовательным порядком, иначе у вас будут плохие времена загрузки и фрагментированные таблицы. (Если ваши поставщики данных похожи на мои, удачи с этим тоже.)

3) Создайте таблицы в своей базе данных, содержащие определения индексов в таблицах загрузки. Создайте подпрограмму, проходящую через них, и отбрасывает все индексы (последние кластеризованные индексы). Это будет быстро, если вы сначала обрезаете таблицы. Загрузите свои данные, затем выполните цикл и заново создайте индексы с нуля (сначала кластеризованные). Используйте разбиение на таблицы, чтобы сделать менее страшным в остальной части системы (например, выполните все вышеприведенные действия в таблицах "загрузка", затем используйте переключение разделов, чтобы переместить загруженные данные в ваши "живые" таблицы). Мне потребовалось мало времени для создания такой системы, но она может и будет работать.

Ответ 7

Перед отключением индекса мы не должны быть ниже:

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

---- Отключить все индексы ALTER INDEX ALL ON [Таблица_Name] DISABLE ИДТИ ---- Включить весь индекс ALTER INDEX ALL ON [Table_Name] REBUILD GO

Подробнее см. "Как отключить - Включить индексы в SQL Server"

Ответ 8

Используйте этот скрипт, чтобы отключить все индексы

-- Disable All Indices
DECLARE @Script NVARCHAR(MAX)
DECLARE curIndices CURSOR FAST_FORWARD READ_ONLY FOR
    SELECT 'ALTER INDEX ' + QUOTENAME(indices.name) + ' ON ' + QUOTENAME(SCHEMA_NAME(tableNames.schema_id))+'.'+ QUOTENAME(tableNames.name) + ' DISABLE'
    FROM
        sys.indexes indices  INNER JOIN 
        sys.tables tableNames ON indices.object_id = tableNames.object_id
    WHERE 
        indices.type_desc = 'NONCLUSTERED' AND 
        indices.name IS NOT NULL AND
        indices.is_disabled = 0;
OPEN curIndices
FETCH NEXT FROM curIndices INTO @Script
WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT @Script
    EXECUTE sp_executesql @Script 

    FETCH NEXT FROM curIndices INTO @Script
END
CLOSE curIndices
DEALLOCATE curIndices

Используйте этот скрипт для перестройки (включения) всех индексов

-- Rebuild All Indices
DECLARE @Script NVARCHAR(MAX)
DECLARE curIndices CURSOR FAST_FORWARD READ_ONLY FOR
    SELECT 'ALTER INDEX ' + QUOTENAME(indices.name) + ' ON ' + QUOTENAME(SCHEMA_NAME(tableNames.schema_id))+'.'+ QUOTENAME(tableNames.name) + ' REBUILD'
    FROM
        sys.indexes indices  INNER JOIN 
        sys.tables tableNames ON indices.object_id = tableNames.object_id
    WHERE 
        indices.type_desc = 'NONCLUSTERED' AND 
        indices.name IS NOT NULL AND
        indices.is_disabled = 1;
OPEN curIndices
FETCH NEXT FROM curIndices INTO @Script
WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT @Script
    EXECUTE sp_executesql @Script 

    FETCH NEXT FROM curIndices INTO @Script
END
CLOSE curIndices
DEALLOCATE curIndices