sql >> Databáze >  >> RDS >> Sqlserver

Automatizovat přestavbu INDEXu na základě výsledků fragmentace?

Používám tento skript. Vezměte prosím na vědomí, že bych vám doporučil přečíst si o dmv, který zde používám, jsou skrytým klenotem v 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

Také mějte na paměti, že tento skript může chvíli běžet a blokovat přístup k vašim tabulkám. Pokud nemáte edice Enterprise, SQL může tabulku ZAMKNOUT při přestavbě indexu. To zablokuje všechny dotazy na tuto tabulku pomocí indexu, dokud nebude dokončena defragmentace indexu. Proto se nedoporučuje spouštět obnovu indexu během provozních hodin pouze během období údržby. Pokud používáte podnikovou edici, můžete k online defragmentaci indexů použít volbu ONLINE=ON. To zabere více místa, ale vaše tabulky nebudou během defragmentace zablokovány/zamčeny.

Pokud potřebujete další informace, zakřičte.

AKTUALIZOVÁNO:

Pokud spouštíte tento dotaz na menší databázi, pravděpodobně můžete použít parametr 'DETAILED' ve volání sys.dm_db_index_physical_stats. Jedná se pravděpodobně o podrobnější zkoumání indexů. Diskuse v komentářích také poukáže na to, že u mnohem větších tabulek se pravděpodobně vyplatí provést skenování SAMPLED, protože to pomůže zkrátit čas potřebný k provedení skenování indexu.



  1. SQL UPDATE všechny hodnoty v poli s připojeným řetězcem CONCAT nefunguje

  2. Migrace schématu:Vztah ke hvězdě

  3. Rails Migration mění sloupec pro použití polí Postgres

  4. Nelze zahodit cizí klíč v MySQL