Désactiver tous les index non groupés

Je sélectionne un certain nombre d'index non groupés à partir de ma database avec les éléments suivants:

SELECT sys.objects.name tableName, sys.indexes.name indexName FROM sys.indexes JOIN sys.objects ON sys.indexes.object_id = sys.objects.object_id WHERE sys.indexes.type_desc = 'NONCLUSTERED' AND sys.objects.type_desc = 'USER_TABLE' 

Je voudrais exécuter ce qui suit sur chacun des résultats:

 ALTER INDEX indexName ON tableName DISABLE 

Comment ferais-je cela? Y a-t-il un meilleur moyen?

MODIFIER

Je fais cela dans le but de tronquer les tables, puis de rebuild avec "ALTER INDEX bla ON table REBUILD". Cela doit être automatisé, donc abandonner et rebuild serait une activité d'entretien un peu plus élevé que je préfère éviter. Est-ce un mauvais plan? J'ai besoin d'un moyen de vider les tables avec un minimum de frais généraux.

Vous pouvez créer les requêtes dans une instruction select, comme ceci:

 DECLARE @sql AS VARCHAR(MAX)=''; SELECT @sql = @sql + 'ALTER INDEX ' + sys.indexes.name + ' ON ' + sys.objects.name + ' DISABLE;' +CHAR(13)+CHAR(10) FROM sys.indexes JOIN sys.objects ON sys.indexes.object_id = sys.objects.object_id WHERE sys.indexes.type_desc = 'NONCLUSTERED' AND sys.objects.type_desc = 'USER_TABLE'; EXEC(@sql); 

Les caractères 13 et 10 sont les returns à la ligne / return chariot, ainsi vous pouvez vérifier la sortie en remplaçant EXEC par PRINT , et il sera plus lisible.

Construire une variable de table avec les index et les noms de tables. Utilisez une boucle pour les parcourir et exécutez une instruction SQL dynamic pour chacun d'entre eux.

 declare @Indexes table ( Num int identity(1,1) primary key clustered, TableName nvarchar(255), IndexName nvarchar(255) ) INSERT INTO @Indexes ( TableName, IndexName ) SELECT sys.objects.name tableName, sys.indexes.name indexName FROM sys.indexes JOIN sys.objects ON sys.indexes.object_id = sys.objects.object_id WHERE sys.indexes.type_desc = 'NONCLUSTERED' AND sys.objects.type_desc = 'USER_TABLE' DECLARE @Max INT SET @Max = @@ROWCOUNT SELECT @Max as 'max' SELECT * FROM @Indexes DECLARE @I INT SET @I = 1 DECLARE @TblName NVARCHAR(255), @IdxName NVARCHAR(255) DECLARE @SQL NVARCHAR(MAX) WHILE @I <= @Max BEGIN SELECT @TblName = TableName, @IdxName = IndexName FROM @Indexes WHERE Num = @I SELECT @SQL = N'ALTER INDEX ' + @IdxName + N' ON ' + @TblName + ' DISABLE;' EXEC sp_sqlexec @SQL SET @I = @I + 1 END 

OTOH il vaudrait peut-être mieux baisser plutôt que DISABLE (ou est-ce une petite différence syntaxique entre Oracle et MS SQL? 🙂 La raison pour laquelle je mentionne est que je me souviens des tables repeuplées et excalculées dénormalisées deux fois par jour et nous étions DROP -désigner tous les index afin de forcer DB à rebuild les index et les plans d'exécution de sproc après avoir chargé une nouvelle date et reconstruit tous les index.

Bien sûr, nous avions un script séparé pour cela car une fois que vous les avez supprimés, les index ne sont plus dans les tables système.

L'utilisation d'un slider pour écrire les choses est plus idiomatique qu'une table temporaire (et légèrement plus courte). Pour réactiver les index, remplacez DISABLE par REBUILD.

 DECLARE cur_indexes CURSOR FOR SELECT sys.objects.name tableName, sys.indexes.name indexName FROM sys.indexes JOIN sys.objects ON sys.indexes.object_id = sys.objects.object_id WHERE sys.indexes.type_desc = 'NONCLUSTERED' AND sys.objects.type_desc = 'USER_TABLE' DECLARE @TblName NVARCHAR(255), @IdxName NVARCHAR(255) DECLARE @SQL NVARCHAR(MAX) open cur_indexes fetch next from cur_indexes into @TblName, @IdxName WHILE @@FETCH_STATUS = 0 BEGIN SELECT @SQL = N'ALTER INDEX ' + @IdxName + N' ON ' + @TblName + ' DISABLE;' EXEC sp_sqlexec @SQL fetch next from cur_indexes into @TblName, @IdxName END close cur_indexes deallocate cur_indexes