89

SELECT WITH (NOLOCK)そのテーブルに影響を与える他の唯一のクエリがクエリである場合、そのテーブルで使用する利点は何だろうと思っていますSELECT

それは SQL Server によってどのように処理されますか? クエリは別のSELECTクエリをブロックしSELECTますか?

SQL Server 2012 と Linq-to-SQL を使用していますDataContext

(編集)

性能について:

  • locked を使用している場合、2 番目SELECTは 1 番目が終了するまで待つ必要がありますか?SELECTSELECT
  • SELECT WITH (NOLOCK)
4

6 に答える 6

198

SELECTSQL Serverの Aは、テーブルの行に共有ロックSELECTを配置します。2 番目の Aも共有ロックを必要とし、それらは互いに互換性があります。

したがって、だれもSELECT他の人をブロックすることはできませんSELECT

クエリ ヒントが使用されるのは、WITH (NOLOCK)(別の接続によって) 挿入中のデータで、まだコミットされていないデータを読み取ることができるようにするためです。

そのクエリ ヒントがないと、その操作のトランザクションがコミット (またはロールバック) されるまで、行 (またはテーブル全体) に排他ロックを配置する進行中の(または) ステートメントSELECTによって、テーブルの読み取りがブロックされる可能性があります。INSERTUPDATE

ヒントの問題WITH (NOLOCK): 最後に (トランザクションがロールバックされた場合) まったく挿入されないデータ行を読み取っている可能性がINSERTあります。 .

役立つかもしれない別のクエリ ヒントがあります - WITH (READPAST)。これによりSELECT、読み取りを試行し、排他的にロックされている行をスキップするようにコマンドに指示します。はSELECTブロックされず、コミットされていない「ダーティ」なデータは読み取られませんが、テーブル内のすべての行が表示されないなど、一部の行がスキップされる場合があります。

于 2012-09-26T21:02:12.873 に答える
35

パフォーマンスでは、選択に集中し続けます。
Shared は読み取りをブロックしません。
共有ロック ブロックが更新されます。
何百もの共有ロックがある場合、共有ロックがクリアされるのを待たなければならないため、排他ロックを取得するために更新に時間がかかります。

デフォルトでは、選択 (読み取り) は共有ロックを取得します。
共有 (S) ロックを使用すると、同時トランザクションでリソースを読み取る (SELECT) ことができます。
他の選択 (1 または 1000) に影響しない共有ロック。

違いは、nolock と共有ロックが更新または挿入操作にどのように影響するかです。

リソースに共有 (S) ロックが存在する間、他のトランザクションはデータを変更できません。

共有ロックは更新をブロックします!
ただし、nolock は更新をブロックしません。

これは、更新のパフォーマンスに大きな影響を与える可能性があります。インサートにも影響を与えます。

ダーティ リード (nolock) は汚い音に聞こえます。部分的なデータを取得することは決してありません。更新によって John が Sally に変更される場合、Jolly を取得することはできません。

私は並行性のために共有ロックをよく使用します。データは読み取られるとすぐに古くなります。次のミリ秒で Sally に変わる John の読み取りは、古いデータです。次のミリ秒で John にロールバックされる Sally の読み取りは、古いデータです。それはミリ秒レベルです。ユーザーが共有ロックを取得している場合は実行に20時間かかり、ユーザーがロックを取得していない場合は実行に4時間かかるデータローダーがあります。この場合の共有ロックにより、データは 16 時間古くなります。

nolocks を間違って使用しないでください。しかし、彼らには居場所があります。バイトが1に設定されているときにチェックをカットし、チェックがカットされたときにそれを2に設定する場合-ノーロックの時間ではありません。

于 2012-09-26T22:31:46.157 に答える
10

私の職場では、多数の PC で同時に実行される非常に大きなシステムがあり、数十万行、場合によっては数百万行の非常に大きなテーブルがあります。

非常に大きなテーブルで SELECT を実行する場合、ユーザーが過去 10 年間に行ったすべてのトランザクションを知りたい場合、テーブルの主キーが効率的な方法で構築されていない場合、クエリに数分かかる場合があります。走る。

次に、アプリケーションが多くのユーザーの PC で同時に実行され、同じデータベースにアクセスする可能性があります。そのため、他の SELECT が読み取っているテーブル (SQL が読み取ろうとしているページ) に誰かが挿入しようとすると、LOCK が発生し、2 つのトランザクションが互いにブロックされます。

SELECT ステートメントに "NO LOCK" を追加する必要がありました。これは、多くのユーザーが同時に多く使用するテーブルに対する巨大な SELECT であり、常に LOCKS を使用していたためです。

私の例が十分に明確かどうかわかりませんか?これは実際の例です。

于 2012-09-26T19:34:02.033 に答える
3

SELECT WITH (NOLOCK)、コミットされていないデータの読み取りを許可します。これはREAD UNCOMMITTED、データベースに分離レベルを設定することと同じです。このNOLOCKキーワードを使用すると、データベース全体の分離レベルを設定するよりもきめ細かい制御が可能になります。

ウィキペディアに役立つ記事があります:ウィキペディア: 分離 (データベース システム)

また、他のスタックオーバーフローの記事でも詳しく説明されています。

于 2014-12-05T08:42:29.327 に答える
1

ロックなしで選択 - 挿入される/挿入されないレコードを選択します。ダーティデータを読み取ります。

たとえば、トランザクションが 1000 行を挿入して失敗したとします。

選択すると、1000行が取得されます。

于 2012-09-26T19:15:23.193 に答える