Mergeステートメントのロックオプションは何ですか?


13

MERGEステートメントを実行するストアドプロシージャがあります。

マージを実行すると、デフォルトでテーブル全体がロックされるようです。

トランザクション内でこのストアドプロシージャを呼び出して、他の処理も実行していて、影響を受ける行のみをロックしたい場合。

ヒントを試しMERGE INTO myTable WITH (READPAST)てみましたが、ロックが少なかったようです。しかし、ms docに、主キーでさえもバイパスして重複キーを挿入する可能性があるという警告がありました。

これが私のテーブルスキーマです:

CREATE TABLE StudentDetails
(
StudentID INTEGER PRIMARY KEY,
StudentName VARCHAR(15)
)
GO
INSERT INTO StudentDetails
VALUES(1,'WANG')
INSERT INTO StudentDetails
VALUES(2,'JOHNSON')
GO

CREATE TABLE StudentTotalMarks
(
Id INT IDENTITY PRIMARY KEY,
StudentID INTEGER REFERENCES StudentDetails,
StudentMarks INTEGER
)
GO
INSERT INTO StudentTotalMarks
VALUES(1,230)
INSERT INTO StudentTotalMarks
VALUES(2,255)
GO

これが私のストアドプロシージャです:

CREATE PROCEDURE MergeTest 
    @StudentId int,
    @Mark int
AS  

WITH Params
AS
(
    SELECT @StudentId as StudentId,
        @Mark as Mark
)
    MERGE StudentTotalMarks AS stm
    USING Params p
    ON stm.StudentID = p.StudentId
    WHEN MATCHED AND stm.StudentMarks > 250 THEN DELETE
    WHEN MATCHED THEN UPDATE SET stm.StudentMarks = p.Mark
    WHEN NOT MATCHED THEN
        INSERT(StudentID,StudentMarks)
        VALUES(p.StudentId, p.Mark);
GO

これが私がロックを観察している方法です:

begin tran
EXEC MergeTest 1, 1

そして別のセッションで:

EXEC MergeTest 2, 2

2番目のセッションは、最初のセッションが完了するのを待ってから続行します。


1
WITH (READPAST)他のセッションによってロックされている行をスキップするようにSQL Serverに指示します。本当によろしいですか?また、このテーブルの何行を変更していますか?テーブルスキーマ(インデックスを含む)とMERGE実行しているステートメントを表示します。
Nick Chammas

@NickChammasは助けてくれてありがとう、私は詳細で質問を更新しました。READPASTは悪いだろうと思います...
John Buchanan

回答:


12

クエリプロセッサに、StudentTotalMarksレコードを見つけるためのより効率的なアクセスパスを与える必要があります。記述されているように、クエリでは、[StudentID] = [@StudentId]各行に残余述語が適用されたテーブルのフルスキャンが必要です。

スキャンプラン

エンジンはU、読み取り時にロックを取得(更新)して、変換デッドロックの一般的な原因に対する基本的な防御策として機能します。この動作は、最初の実行によって(排他的)ロックでUすでにロックされている行のロックを取得しようとすると、2番目の実行がブロックされることを意味しXます。

次のインデックスは、より適切なアクセスパスを提供し、不要なUロックを回避します。

CREATE UNIQUE INDEX uq1 
ON dbo.StudentTotalMarks (StudentID) 
INCLUDE (StudentMarks);

クエリプランにのシーク操作が含まれるようStudentID = [@StudentId]になったため、Uロックはターゲット行でのみリクエストされます。

シークプラン

インデックスはされていない必要であることをUNIQUE(けれども手元に問題を解決するためにINCLUDE、それこのクエリのカバー指標にするために必要とされます)。

製造の表は、アクセスパスの問題を解決する(そして明らかに冗長列を除去することができます)。常に、または制約付きの代替キーを適用する必要があります(正当な理由なしに無意味な代理キーを追加しないでください)。StudentIDPRIMARY KEYStudentTotalMarksIdUNIQUEPRIMARY KEY

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.