Sdílet prostřednictvím


DBCC INDEXDEFRAG (Transact-SQL)

platí pro:SQL Serverazure SQL Managed Instance

Defragmentuje indexy zadané tabulky nebo zobrazení.

Důležitý

Tato funkce bude odebrána v budoucí verzi SQL Serveru. Nepoužívejte tuto funkci v nové vývojové práci a naplánujte úpravu aplikací, které tuto funkci aktuálně používají. Místo toho použijte ALTER INDEX.

platí pro: SQL Server 2008 (10.0.x) a novější verze

Transact-SQL konvence syntaxe

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 ]

Argumenty

database_name | database_id | 0

Databáze obsahující index, který chcete defragmentovat. Pokud je zadána hodnota 0, použije se aktuální databáze. Názvy databází musí splňovat pravidla pro identifikátory .

table_name | table_id | view_name | view_id

Tabulka nebo zobrazení obsahující index, který chcete defragmentovat. Názvy tabulek a zobrazení musí splňovat pravidla pro identifikátory.

index_name | index_id

Název nebo ID indexu, který chcete defragmentovat. Pokud není zadán, příkaz defragmentuje všechny indexy zadané tabulky nebo zobrazení. Názvy indexů musí splňovat pravidla pro identifikátory.

partition_number | 0

Číslo oddílu indexu, který chcete defragmentovat. Pokud není zadán nebo pokud je zadán 0, příkaz defragmentuje všechny oddíly v zadaném indexu.

WITH NO_INFOMSGS

Potlačí všechny informační zprávy, které mají úrovně závažnosti od 0 do 10.

Poznámky

DBCC INDEXDEFRAG defragmentuje úroveň listu indexu tak, aby fyzické pořadí stránek odpovídalo logickému pořadí zleva doprava uzlů typu list, což zlepšuje výkon prohledávání indexu.

Poznámka

Při spuštění DBCC INDEXDEFRAG dochází k defragmentaci indexu sériově. To znamená, že operace v jednom indexu se provádí pomocí jednoho vlákna. Nedojde k žádnému paralelismu. Operace s více indexy ze stejného příkazu DBCC INDEXDEFRAG se také provádějí na jednom indexu najednou.

DBCC INDEXDEFRAG také komprimuje stránky indexu s ohledem na faktor vyplnění zadaný při vytvoření indexu. Všechny prázdné stránky vytvořené z důvodu tohoto komprimace se odeberou. Další informace najdete v tématu Určení faktoru vyplnění indexu.

Pokud index pokrývá více než jeden soubor, DBCC INDEXDEFRAG defragmentaci jednoho souboru najednou. Stránky se mezi soubory nemigrují.

DBCC INDEXDEFRAG hlásí odhadované procento dokončení každých pět minut. DBCC INDEXDEFRAG lze kdykoliv v procesu zastavit a veškerá dokončená práce se zachová.

Na rozdíl od DBCC DBREINDEXnebo operace vytváření indexu obecně platí, že DBCC INDEXDEFRAG je online operace. Nedrží zámky dlouhodobě. Proto DBCC INDEXDEFRAG neblokuje spouštění dotazů ani aktualizací. Vzhledem k tomu, že čas defragmentace souvisí s úrovní fragmentace, může být relativně nefragmentovaný index defragmentován rychleji než nový index lze sestavit. Defragmentace silně fragmentovaného indexu může trvat výrazně déle než opětovné sestavení.

Defragmentace je vždy plně protokolována bez ohledu na nastavení modelu obnovení databáze. Další informace naleznete v tématu ALTER DATABASE (Transact-SQL). Defragmentace silně fragmentovaného indexu může generovat více protokolů, než je vytvoření plně protokolovaného indexu. Defragmentace se však provádí jako řada krátkých transakcí, takže velký protokol není nutný, pokud se zálohování protokolů provádí často nebo pokud je nastavení modelu obnovení JEDNODUCHÉ.

Omezení

DBCC INDEXDEFRAG zahazování stránek listu indexu. Proto pokud je index prokládání s jinými indexy na disku, spuštění DBCC INDEXDEFRAG proti ho indexu neprovádí všechny listové stránky v souvislém indexu. Pokud chcete zlepšit clustering stránek, znovu sestavte index.

DBCC INDEXDEFRAG nelze použít k defragmentaci následujících indexů:

  • Zakázaný index.
  • Index s uzamčením stránky nastaveným na VYPNUTO.
  • Prostorový index.

DBCC INDEXDEFRAG se nepodporuje pro použití v systémových tabulkách.

Sady výsledků

DBCC INDEXDEFRAG vrátí následující sadu výsledků (hodnoty se mohou lišit), pokud je v příkazu zadaný index (pokud není zadán WITH NO_INFOMSGS):

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.

Dovolení

Volající musí vlastnit tabulku nebo být členem role správce systému pevné role serveru, db_owner pevné databázové role nebo db_ddladmin pevné databázové role.

Příklady

A. Defragmentace indexu pomocí DBCC INDEXDEFRAG

Následující příklad defragmentuje všechny oddíly indexu PK_Product_ProductID v tabulce Production.Product v AdventureWorks2022 databázi.

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

B. Defragmentace indexů v databázi pomocí DBCC SHOWCONTIG a DBCC INDEXDEFRAG

Následující příklad ukazuje jednoduchý způsob defragmentace všech indexů v databázi, které jsou fragmentovány nad deklarovanou prahovou hodnotu.

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

Viz také