次のようなクエリを見つけたとき、いくつかのブロッキングを調査していました。
_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の両方でテストしました。
_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)
は推奨される構文です。