DBCC INDEXDEFRAG (Transact-SQL)

Дефрагментирует индексы указанной таблицы или представления.

Важное примечаниеВажно!

В будущей версии Microsoft SQL Server эта возможность будет удалена. Не используйте ее при работе над новыми приложениями и как можно быстрее измените приложения, в которых она в настоящее время используется. Используйте вместо этого инструкцию ALTER INDEX.

Значок ссылки на разделСинтаксические обозначения в Transact-SQL

Синтаксис

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 ] 

Аргументы

  • database_name| database_id | 0
    База данных, содержащая индекс для дефрагментации. Если указано 0, используется текущая база данных. Имена баз данных должны соответствовать правилам для идентификаторов.

  • table_name | table_id | view_name | view_id
    Таблица или представление, содержащие индекс для дефрагментации. Имена таблиц и представлений должны соответствовать правилам для идентификаторов.

  • index_name | index_id
    Имя или идентификатор индекса, подлежащего дефрагментации. Если этот аргумент не указан, дефрагментируются все индексы заданной таблицы или представления. Имена индексов должны соответствовать требованиям, предъявляемым к идентификаторам.

  • partition_number | 0
    Номер секции индекса, которую следует дефрагментировать. Если этот аргумент не указан или равен 0, дефрагментируются все секции заданного индекса.

  • WITH NO_INFOMSGS
    Подавляет все информационные сообщения со степенями серьезности от 0 до 10.

Замечания

Инструкция DBCC INDEXDEFRAG дефрагментирует конечный уровень индекса, приводя физический порядок страниц в соответствие логическому порядку конечных узлов слева направо, что повышает эффективность сканирования индекса.

ПримечаниеПримечание

При выполнении инструкции DBCC INDEXDEFRAG дефрагментация индекса осуществляется последовательно. Это означает, что операции над одним индексом выполняются в одном потоке без параллелизма. Операции над несколькими индексами, относящиеся к одной инструкции DBCC INDEXDEFRAG, выполняются над одним индексом за раз.

Кроме того, инструкция DBCC INDEXDEFRAG сжимает страницы индекса с учетом коэффициента заполнения, указанного при создании индекса. Любые пустые страницы при этом удаляются. Дополнительные сведения см. в разделе Коэффициент заполнения.

Если индекс охватывает более одного файла, инструкция DBCC INDEXDEFRAG дефрагментирует по одному файлу за раз. Страницы не перемещаются между файлами.

Инструкция DBCC INDEXDEFRAG сообщает процент выполнения дефрагментации каждые пять минут. Дефрагментацию можно остановить в любой момент, при этом вся выполненная работа сохраняется.

В отличие от инструкции DBCC DBREINDEX и операций создания индексов вообще, инструкция DBCC INDEXDEFRAG выполняется в режиме в сети. Она не удерживает блокировки длительное время. Таким образом, она не блокирует выполнение запросов или обновлений. Так как время дефрагментации зависит от степени фрагментации, сравнительно нефрагментированный индекс иногда можно дефрагментировать быстрее, чем создать новый индекс. На дефрагментацию сильно фрагментированного индекса может уйти гораздо больше времени, чем на его создание заново.

Процесс дефрагментации всегда полностью регистрируется в журнале независимо от модели восстановления баз данных. Дополнительные сведения см. в разделе ALTER DATABASE (Transact-SQL). Дефрагментация сильно фрагментированного индекса может привести к записи большего объема данных, чем создание индекса с полной регистрацией в журнале. Однако дефрагментация выполняется как ряд кратких транзакций, поэтому она не требует большого журнала, если часто создаются резервные копии журнала или если применяется простая (SIMPLE) модель восстановления.

Ограничения

Инструкция DBCC INDEXDEFRAG перемещает конечные страницы индекса в произвольном порядке. Таким образом, если содержимое индекса чередуется на диске с содержимым других индексов, выполнение инструкции DBCC INDEXDEFRAG для этого индекса не приведет к расположению всех конечных страниц индекса в последовательном порядке. Чтобы улучшить кластеризацию страниц, создайте индекс заново.

Инструкция DBCC INDEXDEFRAG не может быть использована для дефрагментации следующих индексов.

  • Отключенный индекс.

  • Индекс с отключенной блокировкой страниц.

  • Пространственный индекс.

Эта инструкция не поддерживает системные таблицы.

Результирующие наборы

Если в инструкции DBCC INDEXDEFRAG указан индекс (но не указан аргумент 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.

Разрешения

Участник должен быть владельцем таблицы, членом предопределенной роли сервера sysadmin, предопределенной роли базы данных db_owner или предопределенной роли базы данных db_ddladmin.

Примеры

А. Использование DBCC INDEXDEFRAG для дефрагментации индекса

Следующий код дефрагментирует все секции индекса PK_Product_ProductID таблицы Production.Product в базе данных База данных AdventureWorks2008R2.

DBCC INDEXDEFRAG (AdventureWorks2008R2, "Production.Product", PK_Product_ProductID)
GO

Б. Использование DBCC SHOWCONTIG и DBCC INDEXDEFRAG для дефрагментации индексов в базе данных

В следующем примере показан простой способ дефрагментации всех индексов базы данных, фрагментированной сверх определенного порога.

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