DECLARE @Table VARCHAR(255)
DECLARE @cmd NVARCHAR(500)
Declare @SQL Varchar(8000);
DECLARE DatabaseCursor CURSOR FOR
SELECT name FROM master.dbo.sysdatabases
WHERE name NOT IN ('master','model','msdb','tempdb')
ORDER BY 1
OPEN DatabaseCursor
FETCH NEXT FROM DatabaseCursor INTO @Database
WHILE @@FETCH_STATUS = 0
BEGIN
SET @SQL = 'USE ['+@Database+']; '
-- Ensure a USE
SET @SQL = @SQL + ' SET NOCOUNT ON; '
SET @SQL = @SQL + ' DECLARE @objectid int; '
SET @SQL = @SQL + ' DECLARE @indexid int; '
SET @SQL = @SQL + ' DECLARE @partitioncount bigint; '
SET @SQL = @SQL + ' DECLARE @schemaname nvarchar(130); '
SET @SQL = @SQL + ' DECLARE @objectname nvarchar(130); '
SET @SQL = @SQL + ' DECLARE @indexname nvarchar(130); '
SET @SQL = @SQL + ' DECLARE @partitionnum bigint; '
SET @SQL = @SQL + ' DECLARE @partitions bigint; '
SET @SQL = @SQL + ' DECLARE @frag float; '
SET @SQL = @SQL + ' DECLARE @command nvarchar(4000); '
-- Conditionally select tables and indexes from the sys.dm_db_index_physical_stats function
-- and convert object and index IDs to names.
SET @SQL = @SQL + ' SELECT '
SET @SQL = @SQL + ' object_id AS objectid, '
SET @SQL = @SQL + ' index_id AS indexid, '
SET @SQL = @SQL + ' partition_number AS partitionnum, '
SET @SQL = @SQL + ' avg_fragmentation_in_percent AS frag '
SET @SQL = @SQL + ' INTO #work_to_do '
SET @SQL = @SQL + ' FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, ''LIMITED'') '
SET @SQL = @SQL + ' WHERE avg_fragmentation_in_percent > 10.0 AND index_id > 0; '
-- Declare the cursor for the list of partitions to be processed.
SET @SQL = @SQL + ' DECLARE partitions CURSOR FOR SELECT * FROM #work_to_do; '
-- Open the cursor.
SET @SQL = @SQL + ' OPEN partitions; '
-- Loop through the partitions.
SET @SQL = @SQL + ' WHILE (1=1) '
SET @SQL = @SQL + ' BEGIN; '
SET @SQL = @SQL + ' FETCH NEXT '
SET @SQL = @SQL + ' FROM partitions '
SET @SQL = @SQL + ' INTO @objectid, @indexid, @partitionnum, @frag; '
SET @SQL = @SQL + ' IF @@FETCH_STATUS < 0 BREAK; '
SET @SQL = @SQL + ' SELECT @objectname = QUOTENAME(o.name), @schemaname = QUOTENAME(s.name) '
SET @SQL = @SQL + ' FROM sys.objects AS o '
SET @SQL = @SQL + ' JOIN sys.schemas as s ON s.schema_id = o.schema_id '
SET @SQL = @SQL + ' WHERE o.object_id = @objectid; '
SET @SQL = @SQL + ' SELECT @indexname = QUOTENAME(name) '
SET @SQL = @SQL + ' FROM sys.indexes '
SET @SQL = @SQL + ' WHERE object_id = @objectid AND index_id = @indexid; '
SET @SQL = @SQL + ' SELECT @partitioncount = count (*) '
SET @SQL = @SQL + ' FROM sys.partitions '
SET @SQL = @SQL + ' WHERE object_id = @objectid AND index_id = @indexid; '
-- 30 is an arbitrary decision point at which to switch between reorganizing and rebuilding.
SET @SQL = @SQL + ' IF @frag < 30.0 '
SET @SQL = @SQL + ' SET @command = N''ALTER INDEX '' + @indexname + N'' ON '' + @schemaname + N''.'' + @objectname + N'' REORGANIZE''; '
SET @SQL = @SQL + ' IF @frag >= 30.0 '
SET @SQL = @SQL + ' SET @command = N''ALTER INDEX '' + @indexname + N'' ON '' + @schemaname + N''.'' + @objectname + N'' REBUILD''; '
SET @SQL = @SQL + ' IF @partitioncount > 1 '
SET @SQL = @SQL + ' SET @command = @command + N'' PARTITION='' + CAST(@partitionnum AS nvarchar(10)); '
SET @SQL = @SQL + ' EXEC (@command); '
--Print (@command);
SET @SQL = @SQL + ' PRINT N''Executed: '' + @command; '
SET @SQL = @SQL + ' END; '
-- Close and deallocate the cursor.
SET @SQL = @SQL + ' CLOSE partitions; '
SET @SQL = @SQL + ' DEALLOCATE partitions; '
-- Drop the temporary table.
SET @SQL = @SQL + ' DROP TABLE #work_to_do; '
Print @SQL
EXECUTE(@SQL)
FETCH NEXT FROM DatabaseCursor INTO @Database
END
CLOSE DatabaseCursor
DEALLOCATE DatabaseCursor
沒有留言:
張貼留言