21

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

select * from table1 nolock where column1 > 10

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

上記の説明のうち、正しいものはどれですか?その理由は?

4

5 に答える 5

31

最初のステートメントは何もロックしませんが、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

あなたが終わったら。

于 2009-11-12T17:37:15.443 に答える
18

廃止された機能の一覧は、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

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

于 2009-11-12T18:01:04.480 に答える
6

どちらも技術的には正しいですが、WITH キーワードを使用しないことは SQL 2005 の時点で廃止されているため、WITH キーワードの使用に慣れてください - 短い答え、WITH キーワードを使用してください。

于 2009-11-12T17:23:45.490 に答える
5

「WITH (NOLOCK)」を使用してください。

于 2009-11-12T17:24:09.107 に答える