NOLOCKは常に悪いですか?


34

私は、可能な限り効率的にクエリを作成したいレポート開発者です。以前は、運用サーバーでレポートを処理していたためNOLOCK、すべてのクエリで使用できると言っていたDBAと仕事をしていました。

今、私はNOLOCKどんな状況下でも禁止しているDBAと仕事をしています-私のレポート(いくつかのテーブルのインデックスがかなり不足しているため)がレプリケーションとシステムの更新を停止している場合でも。私の意見では、この場合、a NOLOCKは良いことです。

私のSQLトレーニングのほとんどは、非常に異なる意見を持つさまざまなDBAに来ているので、これを多種多様なDBAに依頼したいと思いました。


1
この議論の反対側:dba.stackexchange.com/q/2684/2660
Nick Chammas

回答:


30

レポートがDBAが正しい更新をブロックする場合:絶対に使用しないでくださいNOLOCK。そこという事実です紛争は、あなたがあればということを明確に示しているでしょう汚れを使用すると、あなたは間違ったレポートになるだろう読み込みます。

私の意見では、常により良い選択肢がありNOLOCKます:

  • プロダクションテーブルは実際にのみ読み取られ、変更されることはありませんか?データベースを読み取り専用としてマークしてください!
  • テーブルスキャンはロックの競合を引き起こしますか?テーブルに適切にインデックスを付けると、メリットは複数あります。
  • 適切にインデックスを作成する方法を変更できない/わからない?SNAPSHOT ISOLATIONを使用します。
  • スナップショットを使用するようにアプリを変更できませんか?コミットされたスナップショットの読み取りをオンにします
  • 行のバージョン管理の影響を測定し、パフォーマンスに影響する証拠がありますか?データのインデックスを作成できませんか?そして、あなたは間違ったレポートで大丈夫ですか?その後、少なくともSET TRANSACTION ISOLATION LEVELクエリヒントではなく、を使用してください。すべてのクエリを変更するよりも、後で分離レベルを修正する方が簡単です。

6
注意:コミット済みスナップショットの読み取りをオンにすると、一部のコードが破損する場合があります。
AK

33

必ずしも悪いことではありませ

もちろん、コミットされていない値(ロールバックされて論理的に存在しない可能性がある)を読み取ることができます。また、値を複数回読み取ったり、まったく読み取らないなどの現象も許可します。

このような異常が発生しないことを保証する唯一の分離レベルは、シリアル化可能/スナップショットです。スキャンがこの行に到達する前に行が(キーの更新により)移動されると、反復可能な読み取り値が失われる可能性があります。

nolockただし、デフォルトでは、この分離レベルでは、読み取るページが64ページ以上あると推定される場合、割り当て順序スキャンを使用するため、これらの問題はより発生しやすくなります。インデックスキーの更新によりページ間で行が移動するときに発生する問題のカテゴリと同様に、これらの割り当て順スキャンはページ分割の問題に対して脆弱です(新しく割り当てられたページがポイントよりもファイル内にある場合、行が失われる可能性があります)既にスキャンされているページがファイル内で後のページに分割されている場合は、既にスキャンされているか、2回読み取られます)。

少なくとも、単純なため(単一テーブル)、これらのスキャンの使用を阻止し、キーを取得することが可能である照会でスキャン命じnolock単に追加することによって、ORDER BY index_keyそのようクエリにOrderedの特性がIndexScanありますtrue

しかし、レポート作成アプリケーションが絶対に正確な数値を必要とせず、そのような不一致の大きな可能性を許容できる場合、それは受け入れられるかもしれません。

しかし、確かに、それが魔法の「ターボ」ボタンであることを期待して、すべてのクエリでそれをチャックするべきではありません。同様に、その分離レベルまたは全く結果に異常な結果に遭遇する大きな確率として(エラー「によるデータの移動にNOLOCKでスキャンを続行できませんでした」)のパフォーマンスも場合があるnolock 非常に悪化することができます


3
+1-プロダクションテーブルは変更されないため、頻繁に使用します。
JNK

@JNK変更されないということはどういう意味ですか?
-Kuberchaun

4
マーティン、私はわずかに異なる言葉を提案します:「読まれたコミットされた値は見逃されて、二度以上読まれます」。一部のエキゾチックなケースでは、行を2回以上取得することができます。
AK

@ StarShip3000我々は生産への展開のデータは基本的に読み取り専用で、エンドユーザーのために、そのほとんど自分の意見のNOLOCKヒント持って
JNK

11

顧客はレポートの一貫性のない結果を許容しますか?答えが「いいえ」の場合、NOLOCKを使用しないでください-並行性の下で間違った結果を得ることができます。私はいくつかの例を書いたここではここでは、とここに。これらの例は、READ COMMITTEDおよびREPEATABLE READで一貫性のない出力を示していますが、NOLOCKを使用しても、それらを微調整して誤った結果を得ることができます。


私が作成するレポートのほとんどは、現在のデータでは実行されません。ほとんどのお客様が実行しているレポートは昨日のデータです。その場合、答えは変わりますか?
DataGirl

8

私が作成するレポートのほとんどは、現在のデータでは実行されません。ほとんどのお客様が実行しているレポートは昨日のデータです。その場合、答えは変わりますか?

その場合、もう1つの選択肢があります。
運用データベースでクエリを実行し、ロックとをいじる代わりに、運用データベースNOLOCKのコピーからレポートを実行できます。

毎晩バックアップから自動的に復元されるよう設定できます
顧客のサイトのサーバーでレポートが実行されているようですので、この設定があなたにとって実行可能なソリューションになるかどうかはわかりません。
(しかし、再び...彼らはとにかくバックアップを持っている必要があるので、必要なのはそれらを復元するためのサーバースペースです)

私は社内開発者なので、サーバーとデータベースを完全に制御できるので、これは私にとって簡単です。

少なくとも昨日以前のデータのみを必要とするレポートでは、これを行うことができます。一部のレポートは運用データベースにとどまらなければならないかもしれませんが、少なくともあなたは負荷の一部を別のデータベース(またはさらに良いのは別のサーバー)に移動します。

私も同じような状況にあり
ます。ほぼすべてのレポートにこのような本番データベースのコピーを使用していますが、今日のデータを必要とするクエリがいくつかあります。


私はあなたの答えが好きで、それがうまくいくでしょう-私が完全にコントロールできれば-それはしませんでした。多くの場合、私は完全に制御できず、インデックスを作成できません。実行計画を実行/表示できれば幸運です。
DataGirl
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.