SELECT ステートメントで NOLOCK を発行する正当な理由を誰か提案できますか?
私は、それらが散らばっているいくつかのストアド プロシージャをリファクタリングしていますが、SELECT ステートメントの NOLOCK はほとんど役に立たないことを理解しています。
すでに悪い情報が飛び交っています。選択の WITH(NOLOCK) は、速度が必要な場合に使用するパフォーマンス ツールではありません。この記事を読んで、eSamuel によって提供された回答をダンプします。これは、投票でわかるように、ほとんどの人が考えていることだからです。聞いたことをどうしたらいいのかわからなくて吐き出す人。まず、データとクエリを最適化する方法を学びます。NOLOCK ヒントは、レコードのデッドロックや、NOLOCK が解決策を提供する別の問題を一貫して処理しているシステムでのみ使用する必要があります。
私は金融機関で働いており、1 分間に多数のトランザクションを処理し、顧客や顧客にリアルタイムのレポート機能を提供するOLTPシステムを開発しています。これらの人々は一日中新しいデータの読み取りを実行しており、NOLOCK を使用してレポート クエリを実行しなければ、デッドロックが発生するのは時間の問題です。
十分な注意を払い、評判の良い専門的な情報源から読んでから、NOLOCK を SQL クエリの速度への聖杯としてジャンプする前に、それだけではありません。
したがって、SELECT
同時データ変更クエリによってブロックされることはありません。
一部の人々は、それが魔法の高速化ボタンであると信じて、自由に適用しています. ユースケースが、読み取り後にロールバックされる可能性のあるダーティ(コミットされていない)データを読み取る可能性(したがって、論理的に存在しない)と、特定のタイプの異常の可能性が高いことを受け入れない限り、役に立たないよりも悪い可能性があります。
読み取りコミット分離レベルと比較するとnolock
、スキャンでデータが失われる可能性が高くなり、2 回読み取ったり、データ移動エラーで完全に失敗したりします。
NOLOCK は、トランザクションの READ-UNCOMMITTED と同等です。
つまり、NOLOCK を使用すると、クエリの結果を返す前に既存のロックまたはトランザクションが完了するのを待つ必要がないため、SELECT ステートメントが高速になります。マイナス面は、「ダーティ」データ (コミットされる前に SELECT ステートメントが実行された後にロールバックされた可能性があるもの) を引き戻すことになる可能性があることです。
追加情報については、「SQL Server での NOLOCK および READPAST テーブル ヒントの使用」を参照してください。
NoLocks は、コンテンツがめったに変更されないルックアップ テーブルから読み取る場合に特に役立ちます。
もちろん、nolock の問題は、テーブルが更新されている場合に不正なデータを取得する可能性があることです。nolock を正しく使用できる、常に更新されるテーブルのシナリオがいくつかあります。たとえば、次のテーブルがあります。
UserConfig { id int PRIMARY KEY, is_active_flag ビット, allow_x_feature ビット, allow_y_feature ビット }
選択クエリを実行して ID でフィルタリングしている場合は、このテーブルが頻繁に更新される場合でも nolock を使用する必要があります。