sql >> Base de Datos >  >> RDS >> Sqlserver

¿Automatizar la reconstrucción de INDEX en función de los resultados de fragmentación?

Yo uso este guión. Tenga en cuenta que le aconsejo que lea sobre el dmv que estoy usando aquí, son una joya escondida en 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

También tenga en cuenta que este script puede ejecutarse por un tiempo y bloquear el acceso a sus tablas. A menos que tenga ediciones Enterprise, SQL puede BLOQUEAR la tabla al reconstruir el índice. Esto bloqueará todas las consultas a esa tabla usando el índice hasta que finalice la desfragmentación del índice. Por lo tanto, no se recomienda ejecutar la reconstrucción del índice durante las horas de funcionamiento solo durante las ventanas de mantenimiento. Si está ejecutando la edición empresarial, puede usar la opción ONLINE=ON para desfragmentar índices en línea. Esto utilizará más espacio, pero sus tablas no se bloquearán/bloquearán durante la operación de desfragmentación.

Grita si necesitas más información.

ACTUALIZADO:

Si está ejecutando esta consulta en una base de datos más pequeña, probablemente pueda usar el parámetro 'DETALLE' en la llamada a sys.dm_db_index_physical_stats. Este es probablemente un examen más detallado de los índices. La discusión en los comentarios también señalará que en tablas mucho más grandes probablemente valga la pena hacer un escaneo SAMPLED ya que esto ayudará a reducir el tiempo necesario para hacer el escaneo de índice.