-- Gets Stats Date and Fragmentation Statistics where fragmentation is > 7% use EnVisage go IF EXISTS ( SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'sp_DBMaintenance') AND type IN ( N'P', N'PC' ) ) drop procedure [dbo].[sp_DBMaintenance] go CREATE PROCEDURE [dbo].[sp_DBMaintenance] AS begin truncate table supt_tbl_DbMaintenanceCommands DBCC CHECKIDENT (supt_tbl_DbMaintenanceCommands, reseed, 34) SELECT [Object Name] = object_name(ps.object_id), [Index Name] = i.name, [Fragmentation %] = cast(avg_fragmentation_in_percent as varchar(15)), [Stats Updated] = STATS_DATE(i.object_id, i.index_id) FROM sys.dm_db_index_physical_stats(db_id(), null, null, null, 'sampled') AS ps JOIN sys.indexes AS i ON ps.[object_id] = i.[object_id] AND ps.index_id = i.index_id WHERE (ps.avg_fragmentation_in_percent >= 7 OR ps.avg_page_space_used_in_percent < 75) AND ps.page_count > 8 AND ps.index_id > 0 -- Update Statistics (previous update date is listed after each statement generated) insert into supt_tbl_DbMaintenanceCommands (command,executed) select 'Update Statistics [' + schema_name(o.schema_id) + '].[' + o.name + '] [' + i.name + '] WITH SAMPLE 100 Percent;' ,0 from sys.objects o join sys.indexes i on o.object_id = i.object_id and OBJECTPROPERTY(o.object_id, N'IsUserTable') = 1 and i.index_id > 0 order by isnull(convert(char(10), STATS_DATE(o.object_id, i.index_id), 101), 'N/A') asc insert into supt_tbl_DbMaintenanceCommands (command,executed) -- reorganize indexes (fragmentation will show after each statement generated) SELECT 'alter index [' + i.name + '] on [' + object_name(ps.object_id) + '] reorganize -- ' + cast(avg_fragmentation_in_percent as varchar(15)),0 FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, 'LIMITED') AS ps JOIN sys.indexes AS i ON ps.[object_id] = i.[object_id] AND ps.index_id = i.index_id AND i.type_desc <> 'HEAP' where avg_fragmentation_in_percent > 7 insert into supt_tbl_DbMaintenanceCommands (command,executed) -- rebuild indexes (fragmentation will show after each statement generated) SELECT 'alter index [' + i.name + '] on [' + object_name(ps.object_id) + '] rebuild -- ' + cast(avg_fragmentation_in_percent as varchar(15)),0 FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, 'LIMITED') AS ps JOIN sys.indexes AS i ON ps.[object_id] = i.[object_id] AND ps.index_id = i.index_id AND i.type_desc <> 'HEAP' where avg_fragmentation_in_percent > 7 insert into supt_tbl_DbMaintenanceCommands (command,executed) -- find indexes with 0% fill factor and rebuild with 90% select 'alter index [' + b.name + '] on [' + schema_name(a.schema_id) + '].[' + a.name + '] rebuild with (online = off' + case b.fill_factor when 0 then ', fillfactor = 90' else '' end + ');' ,0 from sys.objects a join sys.indexes b on a.object_id = b.object_id where a.type = 'u' and a.name <> 'dtproperties' and b.fill_factor = 0 and b.name is not NULL declare @max int =0 select @max=max(id) from supt_tbl_DbMaintenanceCommands where isnull(executed,0) = 0 declare @on int=1; while (@on <= @max) begin declare @cmd nvarchar(max) select @cmd=command from supt_tbl_DbMaintenanceCommands where id = @on if not isnull(@cmd,'') = '' begin declare @results nvarchar(max) declare @cd bit=1 BEGIN TRY EXECUTE sp_executesql @cmd set @results='success'; END TRY BEGIN CATCH SELECT @results= ERROR_MESSAGE(),@cd=null END CATCH update supt_tbl_DbMaintenanceCommands set Results=@results, executed=@cd where id=@on end set @on=@on+1 end end