web-dev-qa-db-ja.com

(NOLOCK)vs NOLOCK

次のようなクエリを見つけたとき、いくつかのブロッキングを調査していました。

_SELECT SomeField FROM SomeTable NOLOCK
_

私はNOLOCKを見て、それが他のクエリ(この場合はDELETEステートメント)をどのようにブロックするのか知りたいと思いました。 _sp_lock_を使用してロックを簡単に確認したところ、次のようになりました。

_DB      S   GRANT

TAB     IS  GRANT

PAG    S    GRANT
_

今、私の理解は、NOLOCKはスキーマ安定性ロックのみを取得することになっているということですが、なぜISロックを取得したのですか?

好奇心をそそられました。私はBOLを調べたところ、WITH (NOLOCK)と非推奨の_(NOLOCK)_の2つの使用方法があることを知ったので、それらを試してみることにしました。次のクエリを実行した後、_sp_lock_を実行しました。

_SELECT SomeField FROM SomeTable WITH (NOLOCK)
_
DB S GRANT 
 
 TAB Sch-S GRANT 
_SELECT SomeField FROM SomeTable (NOLOCK)
_
 DB S GRANT 
 
 TAB Sch-S GRANT 

案の定、Schema-Stabilityロックがあります。だから私の質問はこれです:ここで何が起こっているのですか? NOLOCKを使用するための受け入れられた構文がWITH (NOLOCK)または_(NOLOCK)_の場合、単純なNOLOCK(かっこなし)だけで実行するとクエリがエラーにならないのはなぜですか?サポートされている場合、なぜISロックを取得していますか?ここで何が欠けていますか?私はオンラインで答えを探していましたが、これまでのところ不足しています。

私はこれを2008R2と2012の両方でテストしました。

24
Brian
_SELECT SomeField
FROM   SomeTable NOLOCK 
_

_SomeTable AS NOLOCK_のエイリアスを作成したことを意味します。以下を試して、これを明確に見てください。

_SELECT NOLOCK.SomeField
FROM   SomeTable NOLOCK 
_

これは明らかにクエリのロック動作には影響しません。キーワードであり、SSMSで青を表示しているにもかかわらず、NOLOCKは予約されていないTransact-SQLのWordではないため、クエリは失敗しません。構文エラー。予約語のリスト: https://msdn.Microsoft.com/en-us/library/ms189822.aspx

ヒントとして使用するための正しい構文:

  • _(NOLOCK)_は有効ですが、非推奨です。
  • WITH (NOLOCK)は推奨される構文です。
52
Gareth Lyons