既存のテーブルがあります:
_CREATE TABLE dbo.ProofDetails
(
ProofDetailsID int NOT NULL
CONSTRAINT PK_ProofDetails
PRIMARY KEY CLUSTERED IDENTITY(1,1)
, ProofID int NULL
, IDShownToUser int NULL
, UserViewedDetails bit NOT NULL
CONSTRAINT DF_ProofDetails_UserViewedDetails
DEFAULT ((0))
);
_
このテーブルには150,000,000行があります。システムは24時間365日稼働しているため、定期的に発生するメンテナンスウィンドウはありません。
テーブルにインデックスを追加したいのですが、SQL ServerのEnterpriseエディションでは、テーブルへの書き込みアクセスをブロックせずにそれを実行できるはずです。私が使用したコマンドは:
_CREATE INDEX IX_ProofDetails_ProofID_Etc
ON dbo.ProofDetails (ProofID, IDShownToUser)
INCLUDE (UserViewedDetails)
WITH (ONLINE=ON
, ALLOW_ROW_LOCKS=ON
, ALLOW_PAGE_LOCKS=ON
, FILLFACTOR=100
, MAXDOP=4
);
_
SSMSでステートメントを単独で実行しました。 F5。 1分以上実行された後、他のセッションをブロックし始めました。他のセッションをブロックできないため、すぐに_CREATE INDEX
_コマンドをキャンセルしました。
最初の1分間は、_CREATE INDEX
_コマンドをブロックしているものは何もありませんでした。_sys.dm_exec_requests
_は、CXPACKET
の待機タイプのプロセスを示しています-もちろんです。操作が並列化されているので、それは悪いことではないと思います。
_sys.dm_exec_requests
_の出力を調べる時間はあまりありませんでした。クエリ_WHERE session_id = xxx
_から返された行は1つだけでした。ブロックされたセッションがターゲットテーブルに行を挿入しようとしました。
ロックの持続時間はわかりませんが、ステートメントの開始から約2分後にステートメントの実行をキャンセルしたことを除きます。その時点で約1分間ブロックが発生していました。
WITH (ONLINE=ON)
の実装を誤解していますか?または、他に知っておく必要があることはありますか?
サーバーはかなり頑丈なマシンであり、2つのクアッドコアXeon E5-2643 3.3Ghzプロセッサー、192GB RAM、およびSAN 5,000+ iopsに対応できるストレージ。CPUは通常20%未満、= RAMは、ほとんどがSQL Serverによって93%使用されています。WindowsServer 2012とSQL Server 2012だけで、他に何も実行されていません。
Online = onでインデックスを作成する場合、インデックス作成プロセスは、インデックスオブジェクト自体を作成するときにブロックしませんが、プロセスの終わり近くになると、実際に実行するために一定期間スキーマ変更ロック*を取得しますテーブルにインデックスを追加します。このロックタイプは、ロックが解放されるまですべての外部操作をブロックします。これにより、ブロックの問題が発生する可能性があります。
* Sch-M
ロックは、他のすべての場合に必要ですが、新しい非クラスター化インデックスのオンライン構築には必要ありません。新しい非クラスター化インデックスでは、準備フェーズで必要だったのと同じように、最終フェーズではテーブルレベルの共有ロックのみが必要です。
詳細については、このホワイトペーパーを参照してください。
質問のコメントで Mushtaq Mohammed が示唆しているように、次も参照してください: