Използвам този скрипт. Моля, имайте предвид, че бих ви посъветвал да прочетете за dmv, който използвам тук, те са скрит скъпоценен камък в SQL2005+.
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
CREATE TABLE #FragmentedIndexes
(
DatabaseName SYSNAME
, SchemaName SYSNAME
, TableName SYSNAME
, IndexName SYSNAME
, [Fragmentation%] FLOAT
)
INSERT INTO #FragmentedIndexes
SELECT
DB_NAME(DB_ID()) AS DatabaseName
, ss.name AS SchemaName
, OBJECT_NAME (s.object_id) AS TableName
, i.name AS IndexName
, s.avg_fragmentation_in_percent AS [Fragmentation%]
FROM sys.dm_db_index_physical_stats(db_id(),NULL, NULL, NULL, 'SAMPLED') s
INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id]
AND s.index_id = i.index_id
INNER JOIN sys.objects o ON s.object_id = o.object_id
INNER JOIN sys.schemas ss ON ss.[schema_id] = o.[schema_id]
WHERE s.database_id = DB_ID()
AND i.index_id != 0
AND s.record_count > 0
AND o.is_ms_shipped = 0
DECLARE @RebuildIndexesSQL NVARCHAR(MAX)
SET @RebuildIndexesSQL = ''
SELECT
@RebuildIndexesSQL = @RebuildIndexesSQL +
CASE
WHEN [Fragmentation%] > 30
THEN CHAR(10) + 'ALTER INDEX ' + QUOTENAME(IndexName) + ' ON '
+ QUOTENAME(SchemaName) + '.'
+ QUOTENAME(TableName) + ' REBUILD;'
WHEN [Fragmentation%] > 10
THEN CHAR(10) + 'ALTER INDEX ' + QUOTENAME(IndexName) + ' ON '
+ QUOTENAME(SchemaName) + '.'
+ QUOTENAME(TableName) + ' REORGANIZE;'
END
FROM #FragmentedIndexes
WHERE [Fragmentation%] > 10
DECLARE @StartOffset INT
DECLARE @Length INT
SET @StartOffset = 0
SET @Length = 4000
WHILE (@StartOffset < LEN(@RebuildIndexesSQL))
BEGIN
PRINT SUBSTRING(@RebuildIndexesSQL, @StartOffset, @Length)
SET @StartOffset = @StartOffset + @Length
END
PRINT SUBSTRING(@RebuildIndexesSQL, @StartOffset, @Length)
EXECUTE sp_executesql @RebuildIndexesSQL
DROP TABLE #FragmentedIndexes
Също така имайте предвид, че този скрипт може да работи известно време и да блокира достъпа до вашите таблици. Освен ако нямате издания на Enterprise, SQL може да ЗАКЛЮЧИ таблицата при повторно изграждане на индекса. Това ще блокира всички заявки към тази таблица, използващи индекса, докато дефрагментирането на индекса приключи. Поради това не се препоръчва да стартирате повторно изграждане на индекса по време на работни часове само по време на прозорци за поддръжка. Ако използвате корпоративно издание, можете да използвате опцията ONLINE=ON за дефрагментиране на индекси онлайн. Това ще използва повече място, но вашите таблици няма да бъдат блокирани/заключени по време на операцията по дефрагментиране.
Извикайте, ако имате нужда от повече информация.
АКТУАЛИЗИРАНО:
Ако изпълнявате тази заявка в по-малка база данни, вероятно можете да използвате параметъра „DETAILED“ в извикването на sys.dm_db_index_physical_stats. Това вероятно е по-подробно разглеждане на индексите. Дискусията в коментарите също така ще посочи, че на много по-големи таблици вероятно си струва да направите SAMPLED сканиране, тъй като това ще помогне за намаляване на времето, необходимо за сканиране на индекса.