sql >> Database teknologi >  >> RDS >> Sqlserver

Automatisk INDEX-genopbygning baseret på fragmenteringsresultater?

Jeg bruger dette script. Bemærk venligst, at jeg vil råde dig til at læse op om den dmv jeg bruger her, de er en skjult perle i 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

Husk også, at dette script kan køre et stykke tid og blokere adgangen til dine tabeller. Medmindre du har Enterprise-udgaver, kan SQL LÅSE tabellen, når du genopbygger indekset. Dette vil blokere alle forespørgsler til den tabel ved hjælp af indekset, indtil indeksdefragmenteringen er færdig. Det tilrådes derfor ikke kun at køre indeksgenopbygning i driftstiden under vedligeholdelsesvinduer. Hvis du kører enterprise-udgaven, kan du bruge ONLINE=ON-indstillingen til at defragmentere indekser online. Dette vil bruge mere plads, men dine borde vil ikke blive blokeret/låst under defragmenteringen.

Råb op, hvis du har brug for mere information.

OPDATERET:

Hvis du kører denne forespørgsel på en mindre database, kan du sandsynligvis bruge parameteren 'DETAILED' i opkaldet til sys.dm_db_index_physical_stats. Dette er sandsynligvis en mere detaljeret undersøgelse af indeksene. Diskussionen i kommentarerne vil også pege på, at det på meget større tabeller sandsynligvis er værd at lave en SAMPLED-scanning, da dette vil hjælpe med at reducere den tid, der er nødvendig for at lave indeksscanningen.



  1. Indstilling af hentestørrelse i entity framework

  2. MySQL konsoliderer duplikerede dataposter via OPDATERING / SLET

  3. Konverter nemt dine Microsoft Access-forespørgsler med dette nye værktøj!

  4. Betydning af primær nøgle til Microsoft SQL Server 2008