Dela via


DBCC INDEXDEFRAG (Transact-SQL)

gäller för:SQL ServerAzure SQL Managed Instance

Defragmenterar index för den angivna tabellen eller vyn.

Viktig

Den här funktionen tas bort i en framtida version av SQL Server. Undvik att använda den här funktionen i nytt utvecklingsarbete och planera att ändra program som för närvarande använder den här funktionen. Använd ALTER INDEX- i stället.

gäller för: SQL Server 2008 (10.0.x) och senare versioner

Transact-SQL syntaxkonventioner

Syntax

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 ]

Argument

database_name | database_id | 0

Databasen som innehåller indexet för defragmentering. Om 0 anges används den aktuella databasen. Databasnamn måste följa reglerna för identifierare.

table_name | table_id | view_name | view_id

Tabellen eller vyn som innehåller indexet för defragmentering. Tabell- och vynamn måste följa reglerna för identifierare.

index_name | index_id

Namnet eller ID:t för indexet som ska defragmenteras. Om den inte anges defragmenterar instruktionen alla index i den angivna tabellen eller vyn. Indexnamn måste följa reglerna för identifierare.

partition_number | 0

Partitionsnumret för indexet som ska defragmenteras. Om inte anges eller om 0 anges defragmenterar instruktionen alla partitioner i det angivna indexet.

MED NO_INFOMSGS

Undertrycker alla informationsmeddelanden som har allvarlighetsgrad mellan 0 och 10.

Anmärkningar

DBCC INDEXDEFRAG defragmenterar lövnivån för ett index så att sidornas fysiska ordning matchar lövnodernas logiska ordning från vänster till höger, vilket förbättrar indexgenomsökningens prestanda.

Not

När DBCC INDEXDEFRAG körs sker indexdefragmentering seriellt. Det innebär att åtgärden på ett enda index utförs med hjälp av en enda tråd. Ingen parallellitet förekommer. Dessutom utförs åtgärder på flera index från samma DBCC INDEXDEFRAG-instruktion på ett index i taget.

DBCC INDEXDEFRAG komprimerar också sidorna i ett index med hänsyn till den fyllningsfaktor som angavs när indexet skapades. Alla tomma sidor som skapats på grund av den här komprimeringen tas bort. Mer information finns i Ange fyllningsfaktor för ett index.

Om ett index sträcker sig över mer än en fil DBCC INDEXDEFRAG defragmenterar en fil i taget. Sidor migreras inte mellan filer.

DBCC INDEXDEFRAG rapporterar att den uppskattade procentandelen har slutförts var femte minut. DBCC INDEXDEFRAG kan stoppas när som helst i processen och allt slutfört arbete behålls.

Till skillnad från DBCC DBREINDEX, eller indexskapandeåtgärden i allmänhet, är DBCC INDEXDEFRAG en onlineåtgärd. Det håller inte lås på lång sikt. Därför blockerar DBCC INDEXDEFRAG inte körning av frågor eller uppdateringar. Eftersom tiden för defragmentering är relaterad till fragmenteringsnivån kan ett relativt ofragmenterat index defragmenteras snabbare än ett nytt index kan skapas. Ett kraftigt fragmenterat index kan ta betydligt längre tid att defragmentera än att återskapa.

Defragmenteringen loggas alltid helt, oavsett inställningen för databasåterställningsmodellen. Mer information finns i ALTER DATABASE (Transact-SQL). Defragmenteringen av ett kraftigt fragmenterat index kan generera mer logg än när ett fullständigt loggat index skapas. Defragmenteringen utförs dock som en serie korta transaktioner, så en stor logg är onödig om loggsäkerhetskopior görs ofta eller om inställningen för återställningsmodellen är ENKEL.

Inskränkningar

DBCC INDEXDEFRAG blandar indexbladssidor på plats. Om ett index därför interfolieras med andra index på disken, gör körningen DBCC INDEXDEFRAG mot indexet inte alla lövsidor i indexet sammanhängande. Återskapa indexet för att förbättra klustring av sidor.

DBCC INDEXDEFRAG kan inte användas för att defragmentera följande index:

  • Ett inaktiverat index.
  • Ett index med sidlåsning inställt på AV.
  • Ett rumsligt index.

DBCC INDEXDEFRAG stöds inte för användning i systemtabeller.

Resultatuppsättningar

DBCC INDEXDEFRAG returnerar följande resultatuppsättning (värdena kan variera) om ett index anges i -instruktionen (såvida inte WITH NO_INFOMSGS anges):

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.

Behörigheter

Anroparen måste äga tabellen eller vara medlem i sysadmin fast serverroll, db_owner fast databasroll eller db_ddladmin fast databasroll.

Exempel

A. Använda DBCC INDEXDEFRAG för att defragmentera ett index

I följande exempel defragmenteras alla partitioner av PK_Product_ProductID-indexet i tabellen Production.Product i AdventureWorks2022-databasen.

DBCC INDEXDEFRAG (AdventureWorks2022, 'Production.Product', PK_Product_ProductID);
GO

B. Använda DBCC SHOWCONTIG och DBCC INDEXDEFRAG för att defragmentera indexen i en databas

I följande exempel visas ett enkelt sätt att defragmentera alla index i en databas som är fragmenterad över ett deklarerat tröskelvärde.

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

Se även