web-dev-qa-db-ja.com

SQLでのnolockの構文

私はnolockとwith(nolock)を使用してSQLステートメントを見てきました-

select * from table1 nolock where column1 > 10

そして

select * from table1 with(nolock) where column1 > 10

上記の説明のどれが正しいのですか、なぜですか?

18
seenasan

最初のステートメントは何もロックしませんが、2番目のステートメントはロックします。 SQL Server 2005でこれをテストしたところ、

select * from table1 nolock where column1 > 10 --INCORRECT

「nolock」は、そのクエリ内でtable1のエイリアスになりました。

select * from table1 with(nolock) where column1 > 10

必要なnolock機能を実行します。懐疑的?別のウィンドウで実行します

BEGIN TRANSACTION
UPDATE tabl1
 set SomeColumn = 'x' + SomeColumn

テーブルをロックしてから、それぞれのウィンドウで各ロックステートメントを試行します。 1つ目はロックが解除されるのを待ってハングし、2つ目はすぐに実行されます(「ダーティデータ」が表示されます)。発行することを忘れないでください

ROLLBACK

あなたが終わったとき。

29
Philip Kelley

非推奨の機能のリストは SQL Server 2008の非推奨のデータベースエンジン機能 にあります。

  • UPDATEまたはDELETEステートメントのFROM句でNOLOCKまたはREADUNCOMMITTEDを指定する。
  • WITHキーワードを使用せずにテーブルヒントを指定する。
  • 括弧のないHOLDLOCKテーブルヒント
  • テーブルヒント間の区切り文字としてのスペースの使用。
  • ビューを介した複数ステートメントのテーブル値関数(TVF)の呼び出しへのテーブルヒントの間接的な適用。

これらはすべて、SQLの次のリリース後に削除される可能性のある機能のリストに含まれています。つまり、enxtリリースでは、より低いデータベース互換性レベルでのみサポートされる可能性があります。

この問題に関する私の2cは次のとおりです:

  • _from table nolock_とfrom table with(nolock)の両方が間違っています。ダーティリードが必要な場合は、適切な トランザクション分離 レベルを使用する必要があります:_set transaction isolation level read uncommitted_。この方法では、使用される分離レベルが明示的に記述され、1つの「ノブ」から制御されます。これは、ソースを通じて展開され、テーブルヒントのすべての癖(ビューやTVFなどによる間接的なアプリケーション)の影響を受けるのとは対照的です。
  • ダーティリードは悲惨です。必要なのは、99.99%のケースで、コミットされていないデータを読み取るのではなく、競合を減らすことです。適切に設計されたスキーマに対して適切なクエリを記述し、必要に応じてスナップショット分離を展開することにより、競合が軽減されます。ほとんどの場合、いくつかの極端な場合を除き、問題を解決して解決する最良の解決策は、データベースで 読み取りコミットスナップショットを有効にする を有効にし、エンジンにその魔法を働かせることです。

    _ALTER DATABASE MyDatabase SET ALLOW_SNAPSHOT_ISOLATION ON_
    _ALTER DATABASE MyDatabase SET READ_COMMITTED_SNAPSHOT ON_

次に、選択からすべてのヒントを削除します。

18
Remus Rusanu

どちらも技術的には正しいですが、SQL 2005では WITHキーワードを使用しないことは非推奨になっています なので、WITHキーワードの使用に慣れています-短い答え、WITHキーワードを使用してください。

6
boydc7

「WITH(NOLOCK)」を使用します。

5
Rob Garrison

どちらも構文的に正しいです。

NOLOCKはtable1のエイリアスになります。

WITH(NOLOCK)は、データベースの読み取りを高速化する魔法の方法としてよく利用されますが、できる限り使用しないようにしています。

結果セットには、まだコミットされていない、後でロールバックされることが多い行を含めることができます。

エラーまたは結果セットが空になるか、行が欠落するか、同じ行が複数回表示されることがあります。

これは、他のトランザクションがデータの読み取りと同時にデータを移動しているためです。

READ COMMITTEDは、複数のユーザーが同じセルを同時に変更する単一の列内でデータが破損するという追加の問題を追加します。

他の副作用もあります。その結果、最初に期待していた速度の増加が犠牲になります。

これで、二度と使用しないでください。

0