このT-SQLスクリプトは、SUSDBデータベース(Windows Server Update Services (WSUS) で使用されるデータベース)の
基本的なメンテナンス作業を実行します。具体的には、インデックスの最適化と統計情報の更新を行います。
以下に、コードの各部分を解説します。
1. インデックスの断片化解消と最適化
USE SUSDB;
GO
SET NOCOUNT ON;
-- 断片化レベルに基づいて再構築または再編成するインデックスを特定
DECLARE @work_to_do TABLE (
objectid int,
indexid int,
pagedensity float,
fragmentation float,
numrows int
)
DECLARE @objectid int;
DECLARE @indexid int;
DECLARE @schemaname nvarchar(130);
DECLARE @objectname nvarchar(130);
DECLARE @indexname nvarchar(130);
DECLARE @numrows int
DECLARE @density float;
DECLARE @fragmentation float;
DECLARE @command nvarchar(4000);
DECLARE @fillfactorset bit
DECLARE @numpages int
-- 断片化を推定し、必要なインデックスを特定
PRINT 'Estimating fragmentation: Begin. ' + convert(nvarchar, getdate(), 121)
INSERT @work_to_do
SELECT
f.object_id,
index_id,
avg_page_space_used_in_percent,
avg_fragmentation_in_percent,
record_count
FROM
sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'SAMPLED') AS f
WHERE
(f.avg_page_space_used_in_percent < 85.0 and f.avg_page_space_used_in_percent/100.0 * page_count < page_count - 1)
or (f.page_count > 50 and f.avg_fragmentation_in_percent > 15.0)
or (f.page_count > 10 and f.avg_fragmentation_in_percent > 80.0)
PRINT 'Number of indexes to rebuild: ' + cast(@@ROWCOUNT as nvarchar(20))
PRINT 'Estimating fragmentation: End. ' + convert(nvarchar, getdate(), 121)
SELECT @numpages = sum(ps.used_page_count)
FROM
@work_to_do AS fi
INNER JOIN sys.indexes AS i ON fi.objectid = i.object_id and fi.indexid = i.index_id
INNER JOIN sys.dm_db_partition_stats AS ps on i.object_id = ps.object_id and i.index_id = ps.index_id
-- 処理するインデックスのリストのカーソルを宣言
DECLARE curIndexes CURSOR FOR SELECT * FROM @work_to_do
-- カーソルを開く
OPEN curIndexes
-- インデックスをループ処理
WHILE (1=1)
BEGIN
FETCH NEXT FROM curIndexes
INTO @objectid, @indexid, @density, @fragmentation, @numrows;
IF @@FETCH_STATUS < 0 BREAK;
SELECT
@objectname = QUOTENAME(o.name),
@schemaname = QUOTENAME(s.name)
FROM
sys.objects AS o
INNER JOIN sys.schemas as s ON s.schema_id = o.schema_id
WHERE
o.object_id = @objectid;
SELECT
@indexname = QUOTENAME(name),
@fillfactorset = CASE fill_factor WHEN 0 THEN 0 ELSE 1 END
FROM
sys.indexes
WHERE
object_id = @objectid AND index_id = @indexid;
IF ((@density BETWEEN 75.0 AND 85.0) AND @fillfactorset = 1) OR (@fragmentation < 30.0)
SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REORGANIZE';
ELSE IF @numrows >= 5000 AND @fillfactorset = 0
SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD WITH (FILLFACTOR = 90)';
ELSE
SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD';
PRINT convert(nvarchar, getdate(), 121) + N' Executing: ' + @command;
EXEC (@command);
PRINT convert(nvarchar, getdate(), 121) + N' Done.';
END
-- カーソルを閉じて割り当てを解除
CLOSE curIndexes;
DEALLOCATE curIndexes;
IF EXISTS (SELECT * FROM @work_to_do)
BEGIN
PRINT 'Estimated number of pages in fragmented indexes: ' + cast(@numpages as nvarchar(20))
SELECT @numpages = @numpages - sum(ps.used_page_count)
FROM
@work_to_do AS fi
INNER JOIN sys.indexes AS i ON fi.objectid = i.object_id and fi.indexid = i.index_id
INNER JOIN sys.dm_db_partition_stats AS ps on i.object_id = ps.object_id and i.index_id = ps.index_id
PRINT 'Estimated number of pages freed: ' + cast(@numpages as nvarchar(20))
END
GO
§断片化の特定: sys.dm_db_index_physical_stats DMV (Dynamic Management View) を使用して、
インデックスの断片化レベル、ページ密度、レコード数などの情報を取得します。
§断片化の条件: 特定の条件に基づいて、断片化が深刻なインデックスを特定します。
ページ密度が低い(85%未満)場合
ページ数が50を超え、断片化率が15%を超える場合
ページ数が10を超え、断片化率が80%を超える場合
§インデックスの再構築/再編成: 特定されたインデックスに対して、
ALTER INDEX コマンドを使用して再構築(REBUILD)または再編成(REORGANIZE)を実行します。
ページ密度が75%~85%で、FILLFACTORが設定されている場合、または断片化率が30%未満の場合、REORGANIZE を実行します。
レコード数が5000以上でFILLFACTORが設定されていない場合、REBUILD WITH (FILLFACTOR = 90) を実行します。
上記以外の場合は、REBUILD を実行します。
FILLFACTOR: FILLFACTORは、インデックスページの空き領域の割合を指定するもので、挿入パフォーマンスに影響します。
ページ数の計算: 断片化されたインデックスのページ数と、最適化後に解放されたページ数を計算し、結果を出力します。
2. 統計情報の更新
--Update all statistics
PRINT 'Updating all statistics.' + convert(nvarchar, getdate(), 121)
EXEC sp_updatestats
PRINT 'Done updating statistics.' + convert(nvarchar, getdate(), 121)
GO
§統計情報の更新: sp_updatestats ストアドプロシージャを使用して、
データベース内のすべてのテーブルの統計情報を更新します。
統計情報は、クエリのパフォーマンスに影響するため、定期的な更新が重要です。
まとめ
このスクリプトは、SUSDBデータベースのパフォーマンスを維持するために、
インデックスの最適化と統計情報の更新という2つの重要なメンテナンス作業を自動化します。
これにより、データベースのパフォーマンスが向上し、WSUSの安定性が確保されます。
[0回]