3

以下はサンプル クエリです。

INSERT INTO Target (Col1,Col2,Col3,Col4) ----------------Statement#1
Select A.Col1,B.Col2,A.Col3,C.Col4       ----------------Statement#2
FROM A WITH(NOLOCK) INNER JOIN B WITH(NOLOCK)
    ON A.Id = B.ID
    LEFT JOIN C WITH NOLOCK
    ON C.Id = B.ID
Where A.Id = 11

どの段階でロックがテーブルに適用されますか [排他ロック?]、SQL はどのようにクエリを実行しますか?

  1. 結果は、join および where 句に基づいて、テーブル A、B、および C からフェッチされます。
  2. 準備ができたら、テーブルへのデータの挿入を開始し、同時にテーブルにロックを適用します。

実際のデータがページテーブルに書き込まれるとロックされますが、SELECTでINSERT INTOであっても選択中はロックされませんか?

4

2 に答える 2

2

これら 2 つの手順は、クエリ実行の論理的な手順です。SQL Server が物理レベルで実行できることは別の話です。この時点で:

INSERT INTO Target (Col1,Col2,Col3,Col4) ----------------Statement#1
Select A.Col1,B.Col2,A.Col3,C.Col4       ----------------Statement#2
FROM A WITH(NOLOCK) INNER JOIN B WITH(NOLOCK)
    ON A.Id = B.ID
    LEFT JOIN C WITH NOLOCK
    ON C.Id = B.ID
Where A.Id = 11

すべての出力レコード (SELECT節を参照)X lockに対して、RIDまたはKEYターゲット テーブル内 (RIDヒープ/KEYクラスター化インデックスの場合) を取得し、そのレコードを挿入します。この手順は、出力レコードごとに繰り返されます。そのため、ソース テーブルからすべてのレコードを読み取るわけではなく、このステップの後にのみ、ターゲット テーブルへのレコードの挿入を開始します。ソース テーブルのNOLOCKテーブル ヒントにより、これらのテーブルでは Sch-S (スキーマの安定性) ロックのみが使用されます。

ターゲットテーブルで X ロックを取得する場合は、次を使用できます

INSERT INTO Target WITH(TABLOCKX) (Col1,Col2,Col3,Col4)
SELECT ...

挿入のログを最小限に抑えたい場合は、この記事をお読みください。

于 2013-09-13T07:09:15.053 に答える