Поделиться через


DBCC INDEXDEFRAG (Transact-SQL)

Область применения: SQL Server Управляемый экземпляр SQL Azure

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

Внимание

Эта функция будет удалена в будущей версии 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 ]

Аргументы

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 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.

Примеры

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

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

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

B. Использование 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

См. также