web-dev-qa-db-fra.com

Désactiver et réactiver tous les index d'une base de données SQL Server

J'utilise un DTS pour effectuer des tâches dans ma base de données. Dans ce cas, je dois d'abord désactiver all les index de la base de données et les réactiver lorsque le DTS termine son travail.

Existe-t-il un moyen de désactiver tous les index de la base de données et de les réactiver ensuite?

Je sais comment désactiver/activer un par un. Quelqu'un peut-il m'aider à désactiver/activer tout à la fois en tant qu'étape dans le DTS.

19
Eran Meir

Voici un script qui générera des instructions ALTER pour tous les index non clusterisés de votre base de données. Vous pouvez modifier cela facilement pour générer des scripts REBUILD et des scripts pour les index clusterisés. 

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
32
Terence Eccleston

Cela fonctionne pour SQL Server 2008 et les versions plus récentes. Il permet d'utiliser différents schémas et des noms comportant des espaces, des tirets et d'autres caractères spéciaux à citer. Quelle est l'utilisation des crochets [] dans les déclarations SQL?

Ces scripts vont générer du code dans l'onglet de résultats. Vous devez copier/coller dans l'onglet de requête et les exécuter.

Désactiver le 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

Activer le script (reconstruire)

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

Ceci est basé sur une autre réponse ici.

25
Juan Font

Nous pouvons utiliser le script ci-dessous pour désactiver les index 

ALTER INDEX ALL ON [TableName]
DISABLE;

Effectuez votre insertion en bloc dans la table puis exécutez le script ci-dessous.

ALTER INDEX ALL ON [TableName]
REBUILD;
17
Rahul Garg

Pour activer un index, vous devez le reconstruire. Ce script reconstruira tous les index désactivés.

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
Duncan

Vous devrez exécuter un script qui sélectionne le métadate de la table et de l'index. Ensuite, vous pouvez faire un:

ALTER INDEX indexname ON tablename DISABLE; 

Plus tard, vous pouvez exécuter un script similaire pour reconstruire:

ALTER INDEX indexname ON tablename REBUILD; 

Vous pouvez les effectuer un par un ou les rassembler dans une variable NVARCHAR (MAX) et les exécuter en un seul lot. Vous pouvez voir un exemple de code à cette question précédente:

Désactive tous les index non clusterisés

3
RLF

Désactiver les index est une bonne idée pour charger de grandes quantités de données, mais ... le gros problème est celui des index clusterisés. Si vous désactivez un index clusterisé, vous avez désactivé la table entière.

Plusieurs options se suggèrent, et aucune d’elles n’est simple.

1) Parcourez les vues système (sys.indexes), extrayez le nom de la table et de l’index, générez et exécutez du SQL dynamique pour désactiver l’index. Avoir une routine "annuler" pour les réactiver. (Méfiez-vous - s'agissait-il d'un index unique ou d'une contrainte unique?) Cela ne fonctionne, hélas, que si vous n'utilisez pas d'index en cluster. Bonne chance avec ça.

2) Comme pour 1, mais ignorez les index clusterisés. Lorsque vous chargez des données, assurez-vous qu'elles sont chargées dans un ordre séquentiel (index clusterisé), sinon vous aurez des temps de chargement médiocres et des tables fragmentées. (Si vos fournisseurs de données sont comme les miens, bonne chance également avec celui-là.)

3) Créez des tables dans votre base de données contenant les définitions des index de vos tables de «chargement». Construisez une routine qui les parcourt et supprime tous les index (les index clusterisés en dernier). Ce sera rapide si vous tronquez d'abord les tables. Chargez vos données, puis effectuez une boucle et recréez les index à partir de zéro (en cluster en premier). Utilisez le partitionnement de table pour réduire les dégâts sur le reste du système (par exemple, effectuez toutes les opérations ci-dessus sur les tables de «chargement», puis utilisez la commutation de partition pour déplacer les données chargées dans vos tables «actives»). J'ai mis pas mal de temps à construire un tel système, mais cela peut et va fonctionner.

2
Philip Kelley

Utilisez ce script pour désactiver tous les index

-- 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

Utilisez ce script pour reconstruire (activer) tous les index

-- 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
0
Fred