web-dev-qa-db-ja.com

時間がかかりすぎる場合、SQL Serverインデックスの再構築ステートメントをタイムアウトまたはスキップしたい

大規模で断片化されたデータベースでインデックス再構築スクリプトを夜間に実行すると、再構築が完了していないように見えるため、ジョブを停止するインデックスに頻繁に遭遇します。ジョブは停止し、朝は手動でステートメントをキャンセルする必要があり、ロールバックを永久に待機するため、ダウンタイムが発生します。手動で削除して再作成することで、これらの偶発的なインデックスを修正できます。

進捗がほとんどない場合にスクリプトが次の再構築ステートメントに進むことができるように、インデックス再構築ステートメントを自動的にタイムアウトする方法はありますか?

スクリプトは次の形式です。

ALTER INDEX ALL ON [Table1] REBUILD WITH (FILLFACTOR = 90)
ALTER INDEX ALL ON [Table2] REBUILD WITH (FILLFACTOR = 90)
ALTER INDEX ALL ON [Table3] REBUILD WITH (FILLFACTOR = 90)..
4
cloudsafe

まず、無料のスクリプト/ツールの1つを使用してインデックスの再構築を管理することをお勧めします。最もよく知られているのは Ola Hallengren's DBメンテナンススイートです。これにより、インデックスを再編成または再構築する前に、インデックスの断片化の程度を制御できます。

次に、プロセスがハングしているように見える問題がまだある場合は、2つのジョブを作成してみてください。最初のジョブは実際にインデックスの再構築プロセスを実行します。 2番目のジョブは、最初のジョブが必要以上に長く実行されないようにします。

最初のジョブを「インデックスメンテナンスジョブ」と呼びましょう。このジョブをスケジュールするしない

2番目のジョブは、インデックスのメンテナンスを実行するときにスケジュールされ、次のスクリプトを実行します。

DECLARE @jobname nvarchar(128) = N'Index Maint Job';
DECLARE @proc_start_date datetime = GETDATE();

EXECUTE sp_start_job @job_name = @jobname;

WAITFOR DELAY '003:00:00';


IF (EXISTS (SELECT 1
              FROM sysjobactivity ja
                     INNER JOIN sysjobs j ON (ja.job_id = j.job_id)
             WHERE j.name = @jobname
               AND start_execution_date >= @proc_start_date
               AND stop_execution_date IS NULL
           )
   )
BEGIN
    Print N'Aborting job ''' + @jobname + N'''...';
    EXECUTE sp_stop_job @job_name = @jobname;
END
ELSE PRINT N'Job ''' + @jobname + N''' finished.';

これにより、ジョブが起動され、完了するのに十分と思われる時間が与えられるまで待機し、まだ実行されているかどうかを確認し、実行されている場合は停止します。

(私は当初、TRY ... CATCHジョブが実行されておらず、ジョブを停止しようとした場合に発生するエラーをキャッチします。ただし、これはSQL Serverエージェントエラーであり、TRY ... CATCHは処理できません。そのため、代わりにジョブがまだ実行されているかどうかを確認します。)

ここで知っておくべき重要な要素はsp_start_jobはジョブの終了を待ちません。ジョブが開始されると戻ります。したがって、このジョブはその時点で再び自分自身を制御し、好きなだけ待つことができます(現在の設定[WAITFOR DELAY '003:00:00']は3時間です)、ジョブがまだ実行されているかどうかを確認し、実行されている場合は停止します。

FYI:他が指摘したように、インデックスの再編成は徐々に起こります。私は、断片化を解消するためにフラグメント化された大きなPKインデックスを持っていて、Olaのスクリプトを使用してこれを実装し、プロセスが長時間実行されないようにしました。

5
RDFozz

テーブルのすべてのインデックスを再構築する理由。代わりに、インデックスの断片化のしきい値を選択して、ページ数が5Kを超える(たとえば)断片化の数が多いインデックスのみを変更しますか? Olaのインデックスメンテナンス を使用します。 @TimeLimitおよび@LockTimeoutパラメータまたは Minion Reindex(どちらも自由に使用できます-Ola's Indexを使用していますが、minion reindexソリューションは使用していません)

詳細は my answer を参照してください。

2
Kin Shah