「ALL」形式のコマンドによって実行される各インデックス操作に続いて、次のインデックス再構築の前にトランザクションログデータがフラッシュされると想定しました。それは実際にどのように機能するのですか、またはインデックスの再構築は単一のトランザクションの一部であるかのように記録されますか?
1)ログのフラッシュ:SIMPLE復旧モデルは、すべてのトランザクションの後ではなく、チェックポイントでログをクリアします。(詳細情報へのリンク)
2a)すべて再構築:はい、すべて再構築は単一のトランザクションとして機能します。内部のインデックスの再構築には独自のトランザクションがありますが、全体の操作は最後まで完全にはコミットされません。そのため、個々のインデックスを再構築する(および場合によってはCHECKPOINTコマンドを発行する)ことにより、ログファイルの増加を制限できます。
2b)証明!ここに、デモスクリプトがあります。(2016 devに構築)最初に、テーブルとインデックスを使用してテストデータベースをセットアップします。
USE master
GO
CREATE DATABASE Test_RebuildLog
GO
ALTER DATABASE Test_RebuildLog
SET RECOVERY SIMPLE
GO
USE Test_RebuildLog
GO
CREATE TABLE IndexTest
(ID int identity(1,1),
a char(1),
b char(1))
CREATE CLUSTERED INDEX CIX_IndexTest_ID ON IndexTest(ID)
CREATE INDEX IX_IndexTest_a ON IndexTest(a)
CREATE INDEX IX_IndexTest_b ON IndexTest(b)
INSERT IndexTest
(a,b)
VALUES ('a','b'),('z','y'),('s','r')
これで、すべてを再構築し、個別に再構築する間のログアクティビティを比較できます。
CHECKPOINT
GO
ALTER INDEX ALL ON IndexTest REBUILD
SELECT *
FROM sys.fn_dblog(NULL,NULL)
WHERE Operation = 'LOP_COMMIT_XACT'
OR Operation = 'LOP_BEGIN_XACT'
GO
CHECKPOINT
GO
ALTER INDEX CIX_IndexTest_ID ON IndexTest REBUILD
ALTER INDEX IX_IndexTest_a ON IndexTest REBUILD
ALTER INDEX IX_IndexTest_b ON IndexTest REBUILD
SELECT *
FROM sys.fn_dblog(NULL,NULL)
WHERE Operation = 'LOP_COMMIT_XACT'
OR Operation = 'LOP_BEGIN_XACT'
GO
最初の開いているトランザクション(私にとってはトランザクションID 0000:000002fa)は、REBUILD ALLが終了するまでコミットされませんが、インデックスごとの再構築では、それらが連続してコミットされることに注意してください。