sql >> Database >  >> RDS >> Sqlserver

INDEX-reconstructie automatiseren op basis van fragmentatieresultaten?

Ik gebruik dit script. Let op:ik zou je aanraden om je te verdiepen in de dmv die ik hier gebruik, ze zijn een verborgen juweeltje in 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

Houd er ook rekening mee dat dit script een tijdje kan draaien en de toegang tot uw tabellen kan blokkeren. Tenzij u Enterprise-edities hebt, kan SQL de tabel VERGRENDELEN bij het opnieuw opbouwen van de index. Dit blokkeert alle query's naar die tabel met behulp van de index totdat de indexdefragmentatie is voltooid. Het wordt daarom niet aangeraden om indexreconstructie alleen tijdens bedrijfsuren uit te voeren tijdens onderhoudsvensters. Als u een enterprise-editie gebruikt, kunt u de ONLINE=ON-optie gebruiken om indexen online te defragmenteren. Dit zal meer ruimte in beslag nemen, maar je tafels worden niet geblokkeerd/vergrendeld tijdens de defragmentatie.

Schreeuw als je meer informatie nodig hebt.

BIJGEWERKT:

Als u deze query uitvoert op een kleinere database, kunt u waarschijnlijk de parameter 'DETAILED' gebruiken in de aanroep van sys.dm_db_index_physical_stats. Dit is waarschijnlijk een meer gedetailleerd onderzoek van de indexen. De discussie in de opmerkingen zal er ook op wijzen dat het op veel grotere tabellen waarschijnlijk de moeite waard is om een ​​SAMPLED-scan uit te voeren, omdat dit de tijd die nodig is om de indexscan uit te voeren, zal verkorten.



  1. Gegevens draaien in T-SQL

  2. Waarom retourneert mysql_num_rows($result) 1 zelfs als $result een lege resultaatset retourneert?

  3. GEDENTIFICEERD DOOR 'wachtwoord' in MySQL

  4. bulkgegevens importeren in MySQL