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