Defragmentación a partir de la detección de la fragmentación de la DB en SQL Server
Hola a todos!
Compartiré un script que permite desfragmentar automáticamente las tablas que están muy fragmentadas de una DB en SQL Server. Es muy útil ya que ayuda a acelerar y simplificar el mantenimiento de la DB.
-- Set variables BEFORE RUN THIS SQL | |
-- richard.24.se@gmail.com | |
-- ********************************************************************************************* | |
SET NOCOUNT ON | |
DECLARE @reorg_frag_thresh float SET @reorg_frag_thresh = 10.0 | |
DECLARE @rebuild_frag_thresh float SET @rebuild_frag_thresh = 30.0 | |
DECLARE @fill_factor tinyint SET @fill_factor = 0 | |
DECLARE @report_only bit SET @report_only = 0 | |
DECLARE @page_count_thresh smallint SET @page_count_thresh = 1 | |
-- ********************************************************************************************* | |
DECLARE @objectid int | |
DECLARE @indexid int | |
DECLARE @partitioncount bigint | |
DECLARE @schemaname nvarchar(130) | |
DECLARE @objectname nvarchar(130) | |
DECLARE @indexname nvarchar(130) | |
DECLARE @partitionnum bigint | |
DECLARE @partitions bigint | |
DECLARE @frag float | |
DECLARE @page_count int | |
DECLARE @command nvarchar(4000) | |
DECLARE @intentions nvarchar(4000) | |
DECLARE @table_var TABLE( | |
objectid int, | |
indexid int, | |
partitionnum int, | |
frag float, | |
page_count int | |
) | |
INSERT INTO | |
@table_var | |
SELECT | |
[object_id] AS objectid, | |
[index_id] AS indexid, | |
[partition_number] AS partitionnum, | |
[avg_fragmentation_in_percent] AS frag, | |
[page_count] AS page_count | |
FROM | |
sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'LIMITED') | |
WHERE | |
[avg_fragmentation_in_percent] > @reorg_frag_thresh | |
AND | |
page_count > @page_count_thresh | |
AND | |
index_id > 0 | |
DECLARE partitions CURSOR FOR | |
SELECT * FROM @table_var | |
OPEN partitions | |
WHILE (1=1) BEGIN | |
FETCH NEXT | |
FROM partitions | |
INTO @objectid, @indexid, @partitionnum, @frag, @page_count | |
IF @@FETCH_STATUS < 0 BREAK | |
SELECT | |
@objectname = QUOTENAME(o.[name]), | |
@schemaname = QUOTENAME(s.[name]) | |
FROM | |
sys.objects AS o WITH (NOLOCK) | |
JOIN sys.schemas AS s WITH (NOLOCK) | |
ON s.[schema_id] = o.[schema_id] | |
WHERE | |
o.[object_id] = @objectid | |
SELECT | |
@indexname = QUOTENAME([name]) | |
FROM | |
sys.indexes WITH (NOLOCK) | |
WHERE | |
[object_id] = @objectid AND | |
[index_id] = @indexid | |
SELECT | |
@partitioncount = count (*) | |
FROM | |
sys.partitions WITH (NOLOCK) | |
WHERE | |
[object_id] = @objectid AND | |
[index_id] = @indexid | |
SET @intentions = | |
@schemaname + N'.' + | |
@objectname + N'.' + | |
@indexname + N':' + CHAR(13) + CHAR(10) | |
SET @intentions = | |
REPLACE(SPACE(LEN(@intentions)), ' ', '=') + CHAR(13) + CHAR(10) + | |
@intentions | |
SET @intentions = @intentions + | |
N' FRAGMENTATION: ' + CAST(@frag AS nvarchar) + N'%' + CHAR(13) + CHAR(10) + | |
N' PAGE COUNT: ' + CAST(@page_count AS nvarchar) + CHAR(13) + CHAR(10) | |
IF @frag < @rebuild_frag_thresh BEGIN | |
SET @intentions = @intentions + | |
N' OPERATION: REORGANIZE' + CHAR(13) + CHAR(10) | |
SET @command = | |
N'ALTER INDEX ' + @indexname + | |
N' ON ' + @schemaname + N'.' + @objectname + | |
N' REORGANIZE; ' + | |
N' UPDATE STATISTICS ' + @schemaname + N'.' + @objectname + | |
N' ' + @indexname + ';' | |
END | |
IF @frag >= @rebuild_frag_thresh BEGIN | |
SET @intentions = @intentions + | |
N' OPERATION: REBUILD' + CHAR(13) + CHAR(10) | |
SET @command = | |
N'ALTER INDEX ' + @indexname + | |
N' ON ' + @schemaname + N'.' + @objectname + | |
N' REBUILD' | |
END | |
IF @partitioncount > 1 BEGIN | |
SET @intentions = @intentions + | |
N' PARTITION: ' + CAST(@partitionnum AS nvarchar(10)) + CHAR(13) + CHAR(10) | |
SET @command = @command + | |
N' PARTITION=' + CAST(@partitionnum AS nvarchar(10)) | |
END | |
IF @frag >= @rebuild_frag_thresh AND @fill_factor > 0 AND @fill_factor < 100 BEGIN | |
SET @intentions = @intentions + | |
N' FILL FACTOR: ' + CAST(@fill_factor AS nvarchar) + CHAR(13) + CHAR(10) | |
SET @command = @command + | |
N' WITH (FILLFACTOR = ' + CAST(@fill_factor AS nvarchar) + ')' | |
END | |
IF @report_only = 0 BEGIN | |
SET @intentions = @intentions + N' EXECUTING: ' + @command | |
PRINT @intentions | |
EXEC (@command) | |
END ELSE BEGIN | |
PRINT @intentions | |
END | |
PRINT @command | |
END | |
CLOSE partitions | |
DEALLOCATE partitions | |
GO | |
Alter table Relationship rebuild |
Hasta pronto!