平易な英語で、使用することの短所と長所は何ですか
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
.NETアプリケーションとレポートサービスアプリケーションのクエリで?
平易な英語で、使用することの短所と長所は何ですか
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
.NETアプリケーションとレポートサービスアプリケーションのクエリで?
この分離レベルにより、ダーティリードが可能になります。あるトランザクションでは、他のトランザクションによって行われたコミットされていない変更が表示される場合があります。
最高レベルの分離を維持するために、DBMSは通常、データのロックを取得します。これにより、同時実行性が失われ、ロックのオーバーヘッドが高くなる可能性があります。この分離レベルは、このプロパティを緩和します。
いくつかの例とさらなる読み物については、ウィキペディアの記事READ UNCOMMITTED
をチェックすることをお勧めします。
また、StackOverflowの初期の頃に彼と彼のチームがデッドロックの問題にどのように取り組んだかについてのJeffAtwoodのブログ記事をチェックすることにも興味があるかもしれません。ジェフによると:
しかし、
nolock
危険ですか?で無効なデータを読み取ってしまう可能性がありますread uncommitted
か?はい、理論的には。ACIDサイエンスをあなたに落とし始め、試してみたいと言ったときに建物の火災警報器を引く以外は、データベースアーキテクチャの宇宙飛行士が不足することはありませんnolock
。それは本当です:理論は怖いです。しかし、私が思うことは次のとおりです。「理論的には理論と実践の間に違いはありません。実際には違いがあります。」
nolock
データベースのデッドロックの問題に対して、一般的な「何があなたを苦しめるのか」というスネークオイルの修正を使用することは決してお勧めしません。最初に問題の原因を診断してみてください。しかし実際に
nolock
は、あなたが絶対に知っているクエリに追加することは単純で、単純な読み取り専用の問題が問題につながることは決してないようです...あなたが何をしているのかを知っている限り。
READ UNCOMMITTED
あなたが考慮したいと思うかもしれないレベルの1つの代替はREAD COMMITTED SNAPSHOT
です。ジェフをもう一度引用する:
スナップショットは、まったく新しいデータ変更追跡方法に依存しています...単なるわずかな論理的変更ではなく、サーバーがデータを物理的に異なる方法で処理する必要があります。この新しいデータ変更追跡方法を有効にすると、すべてのデータ変更のコピーまたはスナップショットが作成されます。競合時にライブデータではなくこれらのスナップショットを読み取ることにより、読み取り時に共有ロックが不要になり、データベース全体のパフォーマンスが向上する可能性があります。
私のお気に入りのユースケースread uncommited
は、トランザクション内で発生していることをデバッグすることです。
デバッガーでソフトウェアを起動します。コード行をステップ実行している間、トランザクションが開き、データベースが変更されます。コードが停止している間に、クエリアナライザーを開き、読み取りのコミットされていない分離レベルに設定し、クエリを実行して何が起こっているかを確認できます。
また、これを使用して、長時間実行されているプロシージャがスタックしていないかどうかを確認したり、。を使用したクエリを使用してデータベースを正しく更新したりすることもできますcount(*)
。
あなたの会社が過度に複雑なストアドプロシージャを作成するのが好きなら、それは素晴らしいことです。
COUNT(*)
これは、長い挿入クエリの進行状況を確認したり、大まかな見積もり(または大まかなSUM(*)
)を行ったりするのに役立ちます。
言い換えると、ダーティリードクエリが返す結果は、それらを推定値として扱い、それらに基づいて重要な決定を行わない限り、問題ありません。
利点は、状況によっては高速になる可能性があることです。欠点は、結果が間違っている可能性があり(まだコミットされていないデータが返される可能性がある)、結果が再現可能であるという保証がないことです。
精度が気になる場合は、これを使用しないでください。
詳細については、MSDNを参照してください。
ダーティリードまたは分離レベル0のロックを実装します。これは、共有ロックが発行されず、排他ロックが適用されないことを意味します。このオプションを設定すると、コミットされていないデータやダーティなデータを読み取ることができます。トランザクションが終了する前に、データの値を変更したり、データセットの行を表示または非表示にしたりできます。このオプションは、トランザクション内のすべてのSELECTステートメントのすべてのテーブルにNOLOCKを設定するのと同じ効果があります。これは、4つの分離レベルの中で最も制限の少ないものです。
いつ使用しても大丈夫READ UNCOMMITTED
ですか?
良い:絶えず変化する合計を示す大きな集計レポート。
危険:他のほとんどすべて。
良いニュースは、読み取り専用レポートの大部分がその良いカテゴリに分類されることです。
使用しても大丈夫です:
これはおそらく、SSRSなどのビジネスインテリジェンス部門が行うことの大部分をカバーしています。もちろん例外は、その前に$記号が付いているものです。多くの人々は、顧客にサービスを提供し、そのお金を生み出すために必要な関連するコアメトリックに適用されるよりもはるかに熱心にお金を説明します。(私は会計士を非難します)。
危険なとき
詳細レベルまで下がるレポート。その詳細が必要な場合は、通常、すべての行が決定に関連することを意味します。実際、ブロックせずに小さなサブセットをプルできない場合は、それが現在編集されているという正当な理由がある可能性があります。
歴史的なデータ。実用的な違いが生じることはめったにありませんが、ユーザーは絶えず変化するデータが完璧ではないことを理解していますが、静的データについては同じようには感じていません。ダーティリードはここでは害を及ぼしませんが、ダブルリードは時折害を及ぼす可能性があります。とにかく静的データにブロックを設定するべきではないので、なぜそれを危険にさらすのでしょうか。
書き込み機能も備えたアプリケーションにフィードするほぼすべてのもの。
OKシナリオでもOKではない場合。
NOLOCK
、これらのテーブルで実際に使用することはできません。レポートに関しては、クエリがデータベースを詰まらせるのを防ぐために、すべてのレポートクエリでこれを使用します。これができるのは、マイクロ秒単位のデータではなく、履歴データを取得しているためです。
ソースが変更される可能性が非常に低い状況では、READ_UNCOMMITTEDを使用します。
フェッチ操作中にソースが変更される可能性があることがわかっている場合は、READ_UNCOMMITTEDを使用しないでください。
これにより、ダーティリードが表示され、まだコミットされていないトランザクションが表示されます。それが最も明白な答えです。読み取りを高速化するためだけにこれを使用するのは良い考えではないと思います。優れたデータベース設計を使用する場合、それを行う他の方法があります。
何が起こっていないかに注意することも興味深いです。READ UNCOMMITTEDは、他のテーブルロックを無視するだけではありません。また、それ自体でロックが発生することもありません。
大規模なレポートを生成している場合、または大規模で複雑なSELECTステートメントを使用してデータベースからデータを移行している場合を考えてみてください。これにより、トランザクションの期間中、共有テーブルロックにエスカレートされる可能性のある共有ロックが発生します。他のトランザクションはテーブルから読み取ることができますが、更新は不可能です。本番データベースが完全に停止する可能性があるため、本番データベースの場合、これは悪い考えかもしれません。
READ UNCOMMITTEDを使用している場合、テーブルに共有ロックを設定することはありません。いくつかの新しいトランザクションから結果が得られる場合もあれば、データが挿入されたテーブルの場所やSELECTトランザクションが読み取った時間に依存しない場合もあります。たとえば、ページ分割が発生した場合にも、同じデータを2回取得する可能性があります(データはデータファイル内の別の場所にコピーされます)。
したがって、SELECTの実行中にデータを挿入できることが非常に重要である場合は、READUNCOMMITTEDが理にかなっている可能性があります。レポートにエラーが含まれている可能性があることを考慮する必要がありますが、数百万の行に基づいており、結果の選択中に更新されるのはそのうちのいくつかだけである場合、これで「十分」である可能性があります。行の一意性が保証されない可能性があるため、トランザクションもすべて一緒に失敗する可能性があります。
全体としてより良い方法は、SNAPSHOT ISOLATION LEVELを使用することですが、これを使用するには、アプリケーションでいくつかの調整が必要になる場合があります。この一例は、アプリケーションが行を排他的にロックして、他のユーザーがそれを読み取れないようにし、UIで編集モードに入る場合です。SNAPSHOT ISOLATION LEVELには、(特にディスク上で)かなりのパフォーマンスペナルティも伴います。しかし、問題にハードウェアを投入することでそれを克服することができます。:)
また、データベースのバックアップを復元して、データをレポートしたりデータウェアハウスにロードしたりするために使用することも検討してください。
これは、たとえば、既存の行への更新や他のテーブルへのfkがない、挿入専用の監査テーブルなどの単純なテーブルに使用できます。インサートは単純なインサートであり、ロールバックの可能性はほとんどないか、ほとんどありません。
私はいつもREADUNCOMMITTEDを使用しています。それは最小の問題で高速です。他の分離を使用する場合、ほとんどの場合、いくつかのブロッキングの問題が発生します。
Auto Incrementフィールドを使用し、挿入にもう少し注意を払う限り、罰金が科せられます。ブロックの問題に別れを告げることができます。
READ UNCOMMITEDでエラーが発生する可能性がありますが、正直なところ、挿入物が完全な証拠であることを確認するのは非常に簡単です。選択の結果を使用する挿入/更新は、注意する必要がある唯一のものです。(ここでREAD COMMITTEDを使用するか、ダーティリードが問題を引き起こさないことを確認してください)
だから、ダーティリード(特に大きなレポートの場合)に行くと、ソフトウェアはよりスムーズに実行されます...