私のケースのシナリオは、挿入のみを行うプロシージャにパラメーターを渡します。ただし、2 つのスレッドが同じ値を渡そうとする場合があります。
例外をスローせずに、最小限のロックでこの状況を処理するにはどうすればよいですか?
私のパフォーマンス要件は、1 秒あたり少なくとも 10,000 回の挿入です。
編集:列は一意です。タイムスタンプは、挿入前に変更 (調整) される場合があります。
私のケースのシナリオは、挿入のみを行うプロシージャにパラメーターを渡します。ただし、2 つのスレッドが同じ値を渡そうとする場合があります。
例外をスローせずに、最小限のロックでこの状況を処理するにはどうすればよいですか?
私のパフォーマンス要件は、1 秒あたり少なくとも 10,000 回の挿入です。
編集:列は一意です。タイムスタンプは、挿入前に変更 (調整) される場合があります。
重複キーを無視するオプションを使用して、テーブルにインデックスを作成します。重複する行は挿入されず、エラーも発生しません。
例えば
create unique index i1 on #tmp(id) with ignore_dup_key
insert into #tmp values(1,"A")
2> go
(1 row affected)
1> insert into #tmp values(1,"A")
2> go
Duplicate key was ignored.
(0 rows affected)
MERGEステートメントを試す
MSDN から。一般的なシナリオでは、一致する行が存在する場合はテーブル内の 1 つ以上の列を更新し、一致する行が存在しない場合はデータを新しい行として挿入します。これは通常、適切な UPDATE ステートメントと INSERT ステートメントを含むストアド プロシージャにパラメーターを渡すことによって行われます。MERGE ステートメントを使用すると、両方のタスクを 1 つのステートメントで実行できます。
パフォーマンスに関する懸念については、MERGE ステートメントのパフォーマンスの最適化に関するページもあります。
@Martin Smithが指摘しているように、良い解決策があります-私の質問に反していますが、十分にサポートされているように見える理由があります。ここで見つけることができる元の回答は 、 @gbnによって投稿されました。
BEGIN TRY
INSERT etc
END TRY
BEGIN CATCH
IF ERROR_NUMBER() <> 2627
RAISERROR etc
END CATCH
真剣に、これは特に大量の場合、ロックなしで最も高速で最も同時実行です。UPDLOCK がエスカレートされ、テーブル全体がロックされた場合はどうなりますか?
ポール ニールセンによる原文は、こちらでご覧いただけます。- レッスン 4。
誰かが私のような問題を抱えているなら、それを見てみるのは良いことです。