DBCC INDEXDEFRAG (Transact-SQL)

Применимо к: SQL Server Управляемый экземпляр SQL Azure

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

Важно!

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

Применимо к: SQL Server 2008 (10.0.x) и более поздних версий

Соглашения о синтаксисе 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 ]

Примечание

Ссылки на описание синтаксиса Transact-SQL для SQL Server 2014 и более ранних версий, см. в статье Документация по предыдущим версиям.

Аргументы

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.

Remarks

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

Примечание

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

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

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

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

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

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

Ограничения

DBCC INDEXDEFRAG перемешивая конечные страницы индекса на месте. Таким образом, если индекс чередуется с другими индексами на диске, выполнение 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.

Примеры

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

Приведенный ниже код дефрагментирует все секции индекса PK_Product_ProductID таблицы Production.Product в базе данных AdventureWorks2022.

DBCC INDEXDEFRAG (AdventureWorks2022, '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

См. также