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