サイズが7 TB、300,000を超えるテーブルであるSQL 2016データベースに対してOla Hallengren IndexOptimizeスクリプトを使用しています。インデックスを管理するために毎晩6時間のウィンドウしかありません。私はtimelimitパラメーターを使用して、6時間後にジョブを停止します。
問題は、毎晩、インデックスジョブがインデックスの先頭から始まり、約4,000のテーブルのみを通過することです。
インデックスジョブでデータベース内のすべてのインデックスをカバーするにはどうすればよいですか?おそらく、インデックスのサブセットを行う複数のジョブを毎週1つ作成することにより、それとも、ジョブが前に中断した翌日にジョブを再開させる方法はありますか?
すべてのテーブルは同じデータベーススキーマにあります。これはベンダー提供のデータベースです。データベーススキーマを変更できません。
ガイダンスを事前に感謝します。
私の現在のジョブステップは次のとおりです。
EXECUTE [dbo].[IndexOptimize]
@Databases = 'USER_DATABASES',
@FragmentationLow = NULL,
@FragmentationMedium = 'INDEX_REORGANIZE,INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE',
@FragmentationHigh = 'INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE',
@FragmentationLevel1 = 10,
@FragmentationLevel2 = 40,
@UpdateStatistics = 'ALL',
@OnlyModifiedStatistics = 'Y',
@PartitionLevel = 'N',
@MaxDOP = 0,
@SortInTempdb = 'Y',
@TimeLimit = 21600,
@LogToTable = 'Y'
毎晩インデックスをデフラグしないでください。最近のハードウェアでは特に必要ありません(特にシークタイムがゼロのソリッドステートストレージの場合)。毎日のメンテナンスでは、変更された統計情報を更新するだけでよく、パフォーマンスの低下に気付いた場合にのみこれを実行する必要があります(つまり、監視システムの通知内容を確認します)。
Olaのサイトによると、次のようなことができます。
EXECUTE dbo.IndexOptimize
@Databases = 'USER_DATABASES',
@FragmentationLow = NULL,
@FragmentationMedium = NULL,
@FragmentationHigh = NULL,
@UpdateStatistics = 'ALL',
@OnlyModifiedStatistics = 'Y'
インデックスを最適化する必要がある場合(たとえば、大量のデータを削除した場合)にできるもう1つのことは、SQL Serverの Service Broker を使用して複数のメンテナンスプランを設定することですバッチ内のテーブル。
この記事は詳細であり、この返信で要約することは困難ですが、非同期のキューを作成することになります。これにより、エージェントジョブが並行して起動されます。
philcart が何をしたかは、「前に中断した翌日から再開する」のに役立つはずです。
2つのSQLエージェントジョブでIndexOptimiseを実行しています。
毎週実行される最初のジョブでは、以下を使用して最適化が必要なすべてのインデックスを引き出します。
@FragmentationLow = NULL, @FragmentationMedium = 'INDEX_REORGANIZE,INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE', @FragmentationHigh = 'INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE', @FragmentationLevel1 = 5, @FragmentationLevel2 = 30, @LogToTable = 'Y', @Execute = 'N';
これにより、CommandLogテーブルのIndex rebuild/defragコマンドがキャプチャされます。 IndexOptimiseコマンドを実行すると、挿入されたばかりのすべてのレコードの "EndTime"列がnullに設定されます。
次に、毎日、メンテナンスウィンドウ内で、2番目のジョブは単純なカーソルを使用して、EndTimeがNULLの各コマンドを引き出し、時間ウィンドウが経過していない場合はそれを実行します。
DECLARE @sqlCmd nvarchar(max); DECLARE @maxDuration int = 60; DECLARE @startTime datetime = GETDATE(); DECLARE @totalCmds int = (SELECT COUNT(1) FROM [dbo].[CommandLog] WHERE [EndTime] IS NULL); DECLARE @currCount int = 0; DECLARE @cmdSample nvarchar(100); IF @totalCmds > 0 BEGIN -- we have work to do DECLARE cmds CURSOR FAST_FORWARD FOR SELECT [ID],[Command] FROM [dbo].[CommandLog] WHERE [EndTime] IS NULL ORDER BY [ID] DESC OPEN cmds FETCH NEXT FROM cmds INTO @logID, @sqlCmd WHILE (@@FETCH_STATUS = 0 AND (DATEDIFF(MI,@startTime,GETDATE()) < @maxDuration)) BEGIN SET @currCount += 1; SET @cmdSample = LEFT(@sqlCmd,60)+'...'; UPDATE [dbo].[CommandLog] SET [StartTime] = GETDATE() WHERE [ID] = @logID; RAISERROR('Excuting IndexOptimize command for ID:%i (%i of %i) - %s',10,1,@logID, @currCount, @totalCmds,@cmdSample) WITH NOWAIT; EXEC sp_executeSql @command = @sqlCmd; UPDATE [dbo].[CommandLog] SET [EndTime] = GETDATE() WHERE [ID] = @logID; RAISERROR('Command complete for ID:%i (%i of %i) - %s',10,1,@logID, @currCount, @totalCmds,@cmdSample) WITH NOWAIT; FETCH NEXT FROM cmds INTO @logID, @sqlCmd END IF (@currCount < @totalCmds) BEGIN RAISERROR('IndexOptimize finishing due to elapsed time, executed %i commands out of %i',10,1,@currCount, @totalCmds) WITH NOWAIT; END ELSE BEGIN RAISERROR('All commands executed within allowed time window',10,1) WITH NOWAIT; END CLOSE cmds DEALLOCATE cmds END -- we have work to do ELSE BEGIN -- we have work to do RAISERROR('IndexOptimize has nothing to execute',10,1) WITH NOWAIT; END -- we have work to do
https://www.minionware.net/products-1/reindex/でMinion Re-indexのような代替手段を調べることもできます
dBやテーブルの順序などのいくつかの異なる機能がある場合 https://minionware.freshdesk.com/support/solutions/articles/43000040362-minion-reindex-1-2-how-to-reindex-tables-in -a-特定の順序
http://www.midnightsql.com/wp-content/uploads/2015/01/MinionReindexVsIndexOptimize.pdf
@Indexesパラメータを使用すると、個々のインデックスまたはテーブルを指定できます。非常に大きなテーブルで使用し、そのデータベースのメインインデックスジョブから除外します。
詳細はこちら: https://ola.hallengren.com/sql-server-index-and-statistics-maintenance.html 、特にIndexesセクション。
メタテーブルを作成してテーブルのリストにデータを入力し、スケジュールを設定して、カーソルで実行することもできます。