DBCC INDEXDEFRAG (Transact-SQL)
S’applique à : SQL Server Azure SQL Managed Instance
Défragmente les index de la table ou de la vue spécifiée.
Important
Cette fonctionnalité sera supprimée dans une version future de SQL Server. Évitez d'utiliser cette fonctionnalité dans de nouveaux travaux de développement, et prévoyez de modifier les applications qui utilisent actuellement cette fonctionnalité. Utilisez ALTER INDEX à la place.
S’applique à : SQL Server 2008 (10.0.x) et versions ultérieures
Conventions de la syntaxe Transact-SQL
Syntaxe
DBCC INDEXDEFRAG
(
{ database_name | database_id | 0 }
, { table_name | table_id | view_name | view_id }
[ , { index_name | index_id } [ , { partition_number | 0 } ] ]
)
[ WITH NO_INFOMSGS ]
Arguments
database_name | database_id | 0
Base de données contenant l'index à défragmenter. Si 0 est spécifié, la base de données active est utilisée. Les noms de base de données doivent suivre les règles applicables aux identificateurs.
table_name | table_id | view_name | view_id
Table ou vue contenant l'index à défragmenter. Les noms des tables et des vues doivent suivre les règles applicables aux identificateurs.
index_name | index_id
Nom ou ID de l'index à défragmenter. Si aucun ID n'est spécifié, l'instruction défragmente tous les index pour la table ou la vue indiquées. Les noms d'index doivent respecter les règles applicables aux identificateurs.
partition_number | 0
Numéro de la partition de l'index à défragmenter. S'il n'est pas spécifié ou si la valeur 0 est spécifié, l'instruction défragmente toutes les partitions dans l'index indiqué.
WITH NO_INFOMSGS
Supprime tous les messages d'information dont les niveaux de gravité sont compris entre 0 et 10.
Notes
DBCC INDEXDEFRAG
défragmente un index au niveau feuille afin que l'ordre physique des pages corresponde à l'ordre logique (de gauche à droite) des nœuds feuilles, améliorant ainsi les performances d'analyse de l'index.
Notes
Quand DBCC INDEXDEFRAG
est exécuté, la défragmentation de l'index se produit de manière séquentielle. Cela signifie que l'opération est effectuée sur un seul index à l'aide d'un thread unique. Il n'y a aucun parallélisme. En outre, les opérations sur plusieurs index sont effectuées à partir de la même instruction DBCC INDEXDEFRAG
, sur un index à la fois.
DBCC INDEXDEFRAG
compacte également les pages d'un index, en tenant compte du facteur de remplissage spécifié lors de la création de l'index. Toute page vide issue de ce compactage est supprimée. Pour plus d’informations, consultez Spécifier un facteur de remplissage pour un index.
Si un index s'étend sur plusieurs fichiers, DBCC INDEXDEFRAG
défragmente un fichier à la fois. Les pages ne migrent pas d'un fichier à l'autre.
Toutes les cinq minutes, DBCC INDEXDEFRAG
affiche une estimation du pourcentage d'achèvement. DBCC INDEXDEFRAG
peut être arrêté à n'importe quel stade du processus, chaque travail terminé étant conservé.
À l'inverse de DBCC DBREINDEX
ou de la génération d'index en règle générale, DBCC INDEXDEFRAG
est une opération en ligne. Les verrous ne sont pas conservés à long terme. DBCC INDEXDEFRAG
ne bloque donc pas les requêtes ou mises à jour en cours d'exécution. Un index relativement non fragmenté peut être défragmenté plus rapidement que la construction d'un nouvel index, car le temps de défragmentation dépend du volume de fragmentation. Un index fortement fragmenté peut être beaucoup plus long à défragmenter qu'à regénérer.
La défragmentation est toujours complètement enregistrée, quel que soit le paramètre du mode de récupération de la base de données. Pour plus d’informations, consultez ALTER DATABASE (Transact-SQL). La défragmentation d'un index fortement fragmenté peut générer un journal plus volumineux que la création d'un index avec journalisation complète. Toutefois, la défragmentation s'effectue sous la forme d'une série de transactions courtes et ne requiert donc pas un journal volumineux si des sauvegardes de fichier journal sont effectuées fréquemment ou que le paramètre du mode de récupération est SIMPLE.
Restrictions
DBCC INDEXDEFRAG
mélange les pages feuilles de l'index en place. Ainsi, si un index est entrelacé avec d'autres sur le disque, l'exécution de DBCC INDEXDEFRAG
sur cet index ne rend pas toutes ses pages feuilles contiguës. Pour améliorer le clustering des pages, régénérez l'index.
DBCC INDEXDEFRAG
ne peut pas être utilisé pour défragmenter les index suivants :
- un index désactivé ;
- un index dont le verrouillage de page est désactivé (OFF) ;
- un index spatial.
DBCC INDEXDEFRAG
ne peut pas être utilisé sur des tables système.
Jeux de résultats
DBCC INDEXDEFRAG
retourne le jeu de résultats suivant (les valeurs peuvent varier) si un index est spécifié dans l’instruction (sauf si WITH NO_INFOMSGS
est défini) :
Pages Scanned Pages Moved Pages Removed
------------- ----------- -------------
359 346 8
(1 row(s) affected)
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
Autorisations
L’appelant doit être propriétaire de la table ou être membre du rôle serveur fixe sysadmin, du rôle de base de données fixe db_owner ou du rôle de base de données fixe db_ddladmin.
Exemples
R. Utiliser DBCC INDEXDEFRAG pour défragmenter un index
L’exemple suivant défragmente toutes les partitions de l’index PK_Product_ProductID
dans la table Production.Product
de la base de données AdventureWorks2022
.
DBCC INDEXDEFRAG (AdventureWorks2022, 'Production.Product', PK_Product_ProductID);
GO
B. Utiliser DBCC SHOWCONTIG et DBCC INDEXDEFRAG pour défragmenter les index d'une base de données
L'exemple suivant illustre une méthode simple de défragmentation de tous les index d'une base de données fragmentés au-delà d'un seuil déclaré.
/*Perform a 'USE <database name>' to select the database in which to run the script.*/
-- Declare variables
SET NOCOUNT ON;
DECLARE @tablename VARCHAR(255);
DECLARE @execstr VARCHAR(400);
DECLARE @objectid INT;
DECLARE @indexid INT;
DECLARE @frag DECIMAL;
DECLARE @maxfrag DECIMAL;
-- Decide on the maximum fragmentation to allow for.
SELECT @maxfrag = 30.0;
-- Declare a cursor.
DECLARE tables CURSOR FOR
SELECT TABLE_SCHEMA + '.' + TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE';
-- Create the table.
CREATE TABLE #fraglist (
ObjectName CHAR(255),
ObjectId INT,
IndexName CHAR(255),
IndexId INT,
Lvl INT,
CountPages INT,
CountRows INT,
MinRecSize INT,
MaxRecSize INT,
AvgRecSize INT,
ForRecCount INT,
Extents INT,
ExtentSwitches INT,
AvgFreeBytes INT,
AvgPageDensity INT,
ScanDensity DECIMAL,
BestCount INT,
ActualCount INT,
LogicalFrag DECIMAL,
ExtentFrag DECIMAL);
-- Open the cursor.
OPEN tables;
-- Loop through all the tables in the database.
FETCH NEXT
FROM tables
INTO @tablename;
WHILE @@FETCH_STATUS = 0
BEGIN
-- Do the showcontig of all indexes of the table
INSERT INTO #fraglist
EXEC ('DBCC SHOWCONTIG (''' + @tablename + ''')
WITH FAST, TABLERESULTS, ALL_INDEXES, NO_INFOMSGS');
FETCH NEXT
FROM tables
INTO @tablename;
END;
-- Close and deallocate the cursor.
CLOSE tables;
DEALLOCATE tables;
-- Declare the cursor for the list of indexes to be defragged.
DECLARE indexes CURSOR FOR
SELECT ObjectName, ObjectId, IndexId, LogicalFrag
FROM #fraglist
WHERE LogicalFrag >= @maxfrag
AND INDEXPROPERTY (ObjectId, IndexName, 'IndexDepth') > 0;
-- Open the cursor.
OPEN indexes;
-- Loop through the indexes.
FETCH NEXT
FROM indexes
INTO @tablename, @objectid, @indexid, @frag;
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'Executing DBCC INDEXDEFRAG (0, ' + RTRIM(@tablename) + ',
' + RTRIM(@indexid) + ') - fragmentation currently '
+ RTRIM(CONVERT(varchar(15),@frag)) + '%';
SELECT @execstr = 'DBCC INDEXDEFRAG (0, ' + RTRIM(@objectid) + ',
' + RTRIM(@indexid) + ')';
EXEC (@execstr);
FETCH NEXT
FROM indexes
INTO @tablename, @objectid, @indexid, @frag;
END;
-- Close and deallocate the cursor.
CLOSE indexes;
DEALLOCATE indexes;
-- Delete the temporary table.
DROP TABLE #fraglist;
GO