Używam tego skryptu. Proszę zauważyć, że radziłbym przeczytać o dmv, którego używam tutaj, są one ukrytym klejnotem w 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
Pamiętaj też, że ten skrypt może działać przez chwilę i blokować dostęp do twoich tabel. Jeśli nie masz wersji Enterprise, SQL może BLOKOWAĆ tabelę podczas odbudowy indeksu. Spowoduje to zablokowanie wszystkich zapytań do tej tabeli przy użyciu indeksu, dopóki defragmentacja indeksu nie zostanie zakończona. Dlatego nie zaleca się uruchamiania odbudowy indeksu w godzinach pracy tylko podczas okien konserwacyjnych. Jeśli korzystasz z wersji Enterprise, możesz użyć opcji ONLINE=ON do defragmentowania indeksów w trybie online. To zużyje więcej miejsca, ale twoje tabele nie zostaną zablokowane/zablokowane podczas operacji defragmentacji.
Krzycz, jeśli potrzebujesz więcej informacji.
AKTUALIZACJA:
Jeśli uruchamiasz to zapytanie w mniejszej bazie danych, prawdopodobnie możesz użyć parametru „DETAILED” w wywołaniu sys.dm_db_index_physical_stats. Jest to prawdopodobnie bardziej szczegółowe badanie indeksów. Dyskusja w komentarzach wskaże również, że w przypadku znacznie większych tabel prawdopodobnie warto wykonać skanowanie SAMPLED, ponieważ pomoże to skrócić czas potrzebny na skanowanie indeksu.