READ UNCOMMITTED分離レベルを使用するのに最適な状況


10

ご存じのとおり、READ UNCOMMITTEDは、ダーティリードやファントムリードなどが発生する可能性がある最低の分離レベルです。この分離レベルを使用するのに最適な時期はいつですか、どのような理由で使用されるのですか?

実は前に答えを読んでみましたが、例が少ないので完全には理解できませんでした。

回答:


20

SSMSから運用データベースにクエリを実行するときにREAD_UNCOMMITTED(またはNOLOCK)を使用していますが、アプリケーションコードからは定期的に実行していません。この方法(およびMAXDOP 1クエリヒント)は、結果が正しくない可能性があることを理解した上で、データ分析およびトラブルシューティングのためのカジュアルなクエリが本番ワークロードに影響を与えないようにするのに役立ちます。

悲しいことに、私が見るREAD_UNCOMMITTED/ NOLOCKデータの整合性を犠牲にしてブロックを回避するために、生産コードで広く使われています。適切な解決策は、行バージョンの分離レベルである(SNAPSHOTまたはREAD_COMMITTEDREAD_COMMITTED_SNAPSHOTデータベース・オプションON)及び/又はクエリとインデックスチューニングに注目。

最近、コードをレビューしましたが、NOLOCK間違った結果が返されることがあるので、変更が唯一の変更でした。削除NOLOCKは良いことでしたが、行の欠落または重複は通常、大きなテーブルの割り当て順序のスキャン中に発生することを知っていたので、UNION ALLインデックスの効率的な使用を促進する手法をリファクタリングすることも提案しました。クエリは数ミリ秒で実行され、すべての世界で最高の正しい結果が得られます。


7

私は、それの罰金を考えて、いくつかのあなたは結果を受け入れ、他のオプションを持っていない限り、状況。

他のオプションについては、新しいアプリケーションにはRead Committed Snapshot Isolation(RCSI)を、古いアプリケーションにはSNAPSHOT ISOLATION(SI)を使用するように人々を促します。RCSIで競合状態のコードベース全体を簡単にテストすることはできません。

ただし、それらは適切ではない場合があります。tempdbの愛情と思いやりに余分な時間を費やし、バージョンストア(およびtempdb)を拡張してディスクをいっぱいにするトランザクションを開いたままにしないようにする必要がある場合があります。

DBAやSQL Serverの監視と管理を担当する人がいない場合、これらのオプションは危険な場合があります。より一般的には、誰もがサーバーに送信されるコードを完全に制御できるわけではなく、接続文字列またはコードを変更して、問題のクエリのSIを要求できます。

さらに、ほとんどの人はアプリケーション全体でロックの問題を抱えていません。彼らはOLTPデータのレポートなどの問題を抱えています。ライターによってブロックされていないレポートと引き換えに、NOLOCK / RUのトレードオフを受け入れることができる場合は、それに従ってください。

それが何を意味するかを理解していることを確認してください。これは、クエリがロックを取得しないことを意味するのではなく、他のクエリによって取得されたロックを尊重しないことを意味します。

そしてもちろん、問題がライター/ライターのロックである場合、役立つ唯一のオプションはSIですが、エラー処理などで適切に実装するには、開発者の多大な労力が必要になります。


5
そして、問題が本当にOLTPデータについて報告しているだけの場合は、それを何らかの読み取り専用のセカンダリ(AG、ログ配布、レプリケーション、独自のロール)にオフロードします。
アーロンバートランド

3
@AaronBertrandそして、彼らは監視するための2番目のサーバーを持っているでしょう;)
Erik Darling

5

最近のシステムでのREAD UNCOMMITTED の唯一の有効な使用例は、開発中の別のセッションをデバッグするときです。そのため、たとえばストアドプロシージャがまだ実行されているときにセッションが何を行っているかを確認できます。通常、本番システムでは使用されません。多少のパフォーマンスの向上はあるかもしれませんが、長期的にはそれだけの価値はありません。


3

ヘルスケアでいつも使っています。

データの個々の行がクエリの途中で変更されることは驚くほどまれであり、読み取り/書き込みの比率は10,000 / 1です。これらのほとんどは挿入であり、更新ではありません。たとえば、ラボインターフェイスが患者のラボ結果をデータベースに書き込む場合、これらの値は決して変更されません。

データ変更されると、一度に1行ずつ変更されます。誰もが列全体を更新していません(DBAが実際に失敗した場合を除く)。

一方、一連のクエリを実行して、患者が72時間以内にERに戻ってくるようなものをスキャンします。これにより、テーブルが完全に破壊されます。

SQLの10年間で、私はを見たことがありませんRollback Transaction。エンドユーザーエクスペリエンスを中断せずに出入りしたい。OLTPデータベースの速度が低下するリスクが高く、不良データを取得するリスクが低い場合は、NOLOCKを実行します。

それを使うべきでしょうか?多分そうでないかもしれません。一般的に言って、これまで取り組んできたアプリケーションデータベースの多くが適切に設計されているとは言えません。彼らは通常アンチパターンで一杯です。


4
参考までに、部分的に書き込まれた行をnolockで読み取ることができます。
Max Vernon

1
ウーフ!私は本当に上司に別のサーバーを購入してもらうために、これをログ
James

3
READ UNCOMMITTED、特に「Reading Corrupt Data」セクションに関するPaul Whiteのこの気の利いたブログ投稿に興味があるかもしれません。ReadUncommitted Isolation Level
Josh Darnell

1

READ_UNCOMMITTED/NOLOCKデータの正確さが本当に主な目的ではない場合、これは良いオプションです。概算の集計数で十分な場合もあります。例:テーブルのINSERTまたはUPDATEに使用されるストアドプロシージャがあります。更新または挿入されるレコードの数が膨大になる場合があります(数千のレコード)。これらのストアドプロシージャの実行中NOLOCK、ターゲットテーブルで定期的にシンプルな選択クエリを実行して、スムーズに進行するかどうかを確認できます(更新クエリの場合、更新されるレコードのステータス変更列がある場合、その列を使用してgroup byクエリを実行できますNOLOCKステータス変更カウントが常に変化しているかどうかを確認します)。


0

READ UNCOMMITTEDを使用すると、ダーティリードだけでなく、一貫性に関する追加の問題が生じることに注意してください。アクセス方法によっては、行を見逃したり、同じ行を複数回読み取ったりする場合があります。詳細に興味がある場合は、Itzik Ben-Ganの記事を読んでください。


3
行の欠落および行の複数回の読み取りは、デフォルトの読み取りコミットレベルでも可能です。スキャン中にインデックスキー列が更新されて移動した場合。
マーティン・スミス

この回答に関するサイドディスカッションはチャットに移動しました
ポールホワイト9
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.