web-dev-qa-db-ja.com

他のリクエストのリスクなしにオンラインでインデックスを再構築します

SQL Server 2012 Enterprise Editionデータベースがあり、そのインデックスはすぐに断片化します。

これらのインデックスを毎日再編成し、毎週再構築するメンテナンスプランを使用します。再構築はオンラインで行われ、tempdb(Enterprise Edition SQL Server機能)を使用します。

ただし、再構築の2分間は、データベースとの他の接続が影響を受けます。いくつかのタイムアウトまたはデッドロックが発生します。時々、再構築自体もデッドロックで失敗します。

再構築の失敗は問題ありません。もう一度試すことができます。ただし、他の接続がタイムアウトしたり、非常に長くかかったりすることは非常に面倒です。

より低い優先度で再構築を実行する方法、または現在の処理リソースがオンラインの再構築に十分ではない場合に自動的に失敗する方法はありますか?

このデータベースにはダウンタイムのウィンドウがないため、オフラインでインデックスを再構築することはできません。他のリクエストを大幅に妨害することなく、オンラインでインデックスを再構築できる方法はありますか?

6
HugoRune

発生している問題を軽減するために利用できるいくつかのオプションがあります。

/* set the LOCK_TIMEOUT value to the maximum number of milliseconds 
   you want to wait for the ALTER INDEX REBUILD to start
*/
SET LOCK_TIMEOUT 100;

/* this tells SQL Server our ALTER INDEX REBUILD statement should
   be the deadlock victim
*/
SET DEADLOCK_PRIORITY LOW;

/* Rebuild the index */
ALTER INDEX MyIndex 
ON MySchema.MyTable 
REBUILD WITH (
    ONLINE = ON
    , ALLOW_ROW_LOCKS = ON
    , ALLOW_PAGE_LOCKS = ON
    , MAXDOP = 1
    );

SQL Server 2012があることは知っていますが、SQL Server 2014以降ではWAIT_AT_LOW_PRIORITYオプションは、オンラインインデックスの構築操作がスキーマ変更ロックの取得を待機している間、他のセッションの続行を許可するようにSQL Serverに指示します。

ALTER INDEX MyIndex 
ON MySchema.MyTable 
REBUILD WITH (
    ONLINE = ON (WAIT_AT_LOW_PRIORITY (MAX_DURATION = 1 MINUTES, ABORT_AFTER_WAIT = SELF))
    , ALLOW_ROW_LOCKS = ON
    , ALLOW_PAGE_LOCKS = ON
    , MAXDOP = 1
    );

MSDN SQL Server Books Onlineから:

オンラインインデックス再構築のDDLステートメントを実行するには、特定のテーブルで実行されているすべてのアクティブなブロッキングトランザクションを完了する必要があります。オンラインインデックスの再構築が実行されると、このテーブルで実行を開始する準備ができているすべての新しいトランザクションがブロックされます。オンラインインデックスの再構築のためのロックの期間は非常に短いですが、特定のテーブルで開いているすべてのトランザクションが完了するのを待って、新しいトランザクションの開始をブロックすると、スループットに大きな影響を与え、ワークロードのスローダウンまたはタイムアウトが発生し、大幅に制限されます。基になるテーブルへのアクセス。 WAIT_AT_LOW_PRIORITYオプションを使用すると、DBAはオンラインインデックスの再構築に必要なSロックとSch-Mロックを管理でき、3つのオプションのいずれかを選択できます。 3つのケースすべてで、待機時間((MAX_DURATION = n [分]))の間にブロッキングアクティビティがない場合、オンラインインデックスの再構築は待機せずにすぐに実行され、DDLステートメントが完了します。

5
Max Vernon