Certaines opérations sur les index ne peuvent pas être réalisées via la commande ALTER. Ainsi, par exemple, la modification de données telles que le taux de remplissage (Fillfactor) ou encore les paramétrages d’autorisation de verrous ligne / page, nécessite le passage par la commande de création CREATE INDEX.
Le problème est qu’il est nécessaire de générer un script de reconstruction des index, en y apportant éventuellement quelques modifications pour notre besoin propre (modifier le taux de remplissage, …).
Pour cela, je vous propose le script suivant, qui générera un ensemble de lignes de commandes que vous pourrez aisément intégrer dans votre processus d’upgrade de base.
-- Générateur de script de création d'index -- Auteur : Jean-Nicolas BERGER (www.sqlserver.fr) set nocount on -- Déclaration de variables declare @Liste table (index_id int, object_id int, DebutCreate varchar(max), FinCreate varchar(max), MilieuInclude varchar(max) DEFAULT ') INCLUDE (', ListeColonnes varchar(max), ListeColonnesIncluses varchar(max)) declare @index_id int,@object_id int declare @ListeColonnes varchar(max), @ListeColonnesIncluses varchar(max) -- Index à prendre en compte, avec mise en place des paramètres insert into @Liste(index_id,object_id,DebutCreate,FinCreate) select i.index_id,t.object_id, 'CREATE ' + case when i.is_unique=1 then 'UNIQUE ' else '' end + case when i.index_id=1 then 'CLUSTERED ' else 'NONCLUSTERED ' end + 'INDEX '+QUOTENAME(i.name)+' ON '+QUOTENAME(s.name)+'.'+QUOTENAME(t.name)+' (', case when i.filter_definition is null then '' else ') WHERE ('+ i.filter_definition end +') WITH (' + 'PAD_INDEX=' + case when i.is_padded=1 then 'ON' else 'OFF' end + ',FILLFACTOR = ' + convert(varchar,case when i.fill_factor=0 then 100 else i.fill_factor end) + ',SORT_IN_TEMPDB = ON' + ',IGNORE_DUP_KEY = ' + case when i.ignore_dup_key=1 then 'ON' else 'OFF' end + ',DROP_EXISTING = ON' + ',ALLOW_ROW_LOCKS = ' + case when i.allow_row_locks=1 then 'ON' else 'OFF' end + ',ALLOW_PAGE_LOCKS = ' + case when i.allow_page_locks=1 then 'ON' else 'OFF' end +') ON '+QUOTENAME(ds.name) +case when ds.type='PS' then '('+QUOTENAME(cp.name)+')' else '' end from sys.indexes i join sys.tables t on t.object_id=i.object_id join sys.schemas s on s.schema_id=t.schema_id join sys.data_spaces ds on ds.data_space_id=i.data_space_id left join sys.index_columns icp on icp.object_id=i.object_id and icp.index_id=i.index_id and icp.partition_ordinal=1 left join sys.columns cp on cp.object_id=t.object_id and cp.column_id=icp.column_id where i.type in (1,2) and t.type='U' and i.is_primary_key=0 -- Pour chaque index DECLARE curseur CURSOR FOR SELECT index_id,object_id FROM @Liste OPEN curseur FETCH NEXT FROM curseur INTO @index_id,@object_id WHILE @@FETCH_STATUS = 0 BEGIN -- Construction de la liste des colonnes principales SELECT @ListeColonnes=',' SELECT @ListeColonnes+=quotename(c.name)+case when ic.is_descending_key=1 then ' DESC' else ' ASC' end+',' FROM sys.index_columns ic join sys.columns c on c.object_id=ic.object_id and c.column_id=ic.column_id where ic.object_id=@object_id and ic.index_id=@index_id and ic.key_ordinal>0 order by key_ordinal -- Construction de la liste des colonnes incluses SELECT @ListeColonnesIncluses=',' SELECT @ListeColonnesIncluses+=quotename(c.name)+',' FROM sys.index_columns ic join sys.columns c on c.object_id=ic.object_id and c.column_id=ic.column_id where ic.object_id=@object_id and ic.index_id=@index_id and ic.key_ordinal=0 -- Mise en forme des listes de colonnes SELECT @ListeColonnes=SUBSTRING(@ListeColonnes,2,len(@ListeColonnes)-2) select @ListeColonnesIncluses=nullif(@ListeColonnesIncluses,',') SELECT @ListeColonnesIncluses=SUBSTRING(@ListeColonnesIncluses,2,len(@ListeColonnesIncluses)-2) update @Liste set ListeColonnes=@ListeColonnes, ListeColonnesIncluses=@ListeColonnesIncluses where object_id=@object_id and index_id=@index_id FETCH NEXT FROM curseur INTO @index_id,@object_id END CLOSE curseur DEALLOCATE curseur -- Présentation du résultat final select DebutCreate + ListeColonnes + isnull(MilieuInclude+ListeColonnesIncluses, '') + FinCreate +';' from @Liste
Comme vous pouvez le constater, ce script présente les principaux paramètres de configuration d’index (colonnes normales avec ordre ascendant ou descendant, colonnes incluses, filtres, partitionnement, …).
Il se concentre uniquement sur les index hors clé primaire, un script dédié étant présenté pour cela dans un autre article.
N’hésitez pas à le tester et à m’en donner des nouvelles.
Ping : Générer un script de reconstruction de clés primaires | SQLServer.fr