2009-03-26 40 views
512

with (nolock)をクエリに使用することの意味を説明することができます。"with(nolock)"を使用する場合

たとえば、トランザクション率が高く、特定のテーブルに大量のデータがある銀行業務アプリケーションを使用している場合、どのような種類のクエリで問題ないのですか?あなたはいつもそれを使用するべきである/使用しない場合がありますか?

+0

私はhttp://stackoverflow.com/questions/3836282/what-are-locking-issues-in-olapとhttp://stackoverflow.com/questions/3836032/what-are-locking-deadlocking-主にジョナサン・アレンの答えhttp://stackoverflow.com/questions/686724/sql-when-should-you-use-with-nolock/686941#686941 –

+1

ここに1つのリンク - http:// www .mssqltips.com/sqlservertip/2470/understanding-the-sql-server-nolock-hint/ – Steam

+1

ここでは、NOLOCKを使用した場合の優れた概要を示します。http://blogs.msdn.com/b/davidlean/archive/2009 /04/06/sql-server-nolock-hint-other-other-ideas.aspx – Bryan

答えて

368

は、トランザクション分離レベルとしてREAD UNCOMMITEDを使用するのと同じです。したがって、ロールバックされたコミットされていない行、つまり決してデータベースに格納されていないデータを読み取る危険性があります。したがって、他の操作によって読み取りがデッドロックされるのを防ぐことができますが、それにはリスクが伴います。トランザクション率の高い銀行業務アプリケーションでは、IMHOで解決しようとしている問題があれば、それは正しい解決策にはならないでしょう。

+136

ほとんどの銀行業務アプリケーションは、ビジネス上の意味でトランザクション的であるため、安全にnolockを使用できます。あなたは新しい行を書くだけで、あなたはそれらを更新することはありません。 –

+0

@ Grauenwolf-非常に興味深い点です。 –

+43

@ Grauenwolf-挿入されているがコミットされていない行は、依然としてダーティな読み込みにつながる可能性があります。 – saasman

14

データを読み取るだけで、まだコミットされていないデータを戻すことができるかどうかは気にしません。

それは、読み出し動作に高速化することができますが、私は本当に一般的にはどのくらい....

によって言うことができない、私はそれを使用しないことをお勧めします - コミットされていないデータを読み込むことはせいぜい少し混乱することができます。

(NOLOCK)WITHマーク

+1

SQL Server 2005に行のバージョニングがあるため、nolocksが必要なくなったということに言及していただければ幸いです。 –

+0

「with(nolock)」は、SQL Server 2005でもまだまだ存在しますが、そのメリットはよりスリムでスリムになりつつあります。 –

6

「汚れた」データで問題がない場合は、nolockを使用してください。つまり、ノーロックは、変更されたデータやコミットされていないデータの処理中のデータも読み取ることができます。

高いトランザクション環境で使用することは一般的にはお勧めできません。そのため、クエリではデフォルトのオプションではありません。

+2

あなたが必要とする唯一の時間は、トランザクションの高い環境です。あなたのテーブルがほとんどアイドルであれば、それによって何も得られません。 –

7

私はこれを行うために「次のバッチ」を取得するために使用しました。この場合、正確な項目は重要ではなく、この同じクエリを実行している多くのユーザーがいます。

+1

私たちは、作業の待ち行列を持つバックグラウンドタスクを提示するのに似たようなことをします。特定のレコードになったときに選択基準に一致する場合、次のレコードに移動します。 – TripeHound

8

ファイナンストランザクションを処理する場合は、nolockを使用することは決してありません。 nolockは、多くの更新プログラムを含む大きなテーブルから選択するのに最適です。取得するレコードが期限切れになる可能性があるかどうかは気にしません。

財務レコード(ほとんどのアプリケーションのほぼすべての他のレコード)の場合、書面に書き込まれたレコードからデータを読み込み、正しいデータを取得できない可能性があるため、nolockが大惨事になります。

+4

驚くべきことに、財務データを扱う場合、これは問題ではありません。一時的に偽のデータを読み取っても行は編集されず、アカウントは一日の終わりに調整されるため、何も行われません。 –

15

通常、大丈夫なもう1つのケースは、データがすでに古くなっていて書き込みが行われていないレポートデータベースにある場合です。ただし、このオプションは、デフォルトの分離レベルを変更して、管理者がデータベースまたはテーブルレベルで設定する必要があります。

通常の場合:非常にの場合は古いデータを読み込んでも問題ありません。覚えておくべき重要なことは、が間違っていることが非常に簡単であることです。たとえば、クエリを作成するときに問題がなくても、今後これらの更新をより重要なものにするために、データベースで何かが変更されないことを確認してください。

私はまた、おそらくではないという考えを第2にします。バンキングアプリでは良いアイデアです。または在庫アプリ。あるいは、トランザクションについて考えているところです。

+3

銀行業務に携わる人として、ノーロックは問題ではないと言わざるを得ない。挿入されていても更新または削除されない行であるトランザクション・レコードは、コミットされていないデータを読み取る際の問題に対して驚くほど耐性があります。 –

6

私は、特に高性能のSQLServer 2000データベースで(ノーロック)ヒントを使用します。しかし、SQL Server 2005ではそれが必要であるとは確信していません。私は最近、多くのSPIDレコードロックに気付いていたので、クライアントのDBAの要求に応じてSQL Server 2000にヒントを追加しました。

私が言うことができるのは、ヒントを使用しても私たちを傷つけることはなく、ロック問題が解決されたように見えることです。特定のクライアントのDBAは基本的にヒントを使用するよう主張しました。

ところで、私が扱うデータベースはエンタープライズの医療保険制度のバックエンドなので、数百万のレコードと多くの結合で20以上のテーブルについて話しています。私は通常、結合の各テーブルにWITH(ノーロック)ヒントを追加します(派生テーブルでない限り、その特定のヒントは使用できません)。

+1

SQL Server 2005には、行のバージョニングが追加されているため、ノーロックの必要性が大幅に軽減されます。私たちは最近アップグレードし、DBAの使用を中止するためにDBAをトレーニングしていません。 –

23

NOLOCKREAD UNCOMMITTEDと同等ですが、 UPDATEまたはDELETEステートメントの場合

UPDATEまたはDELETE文には使用しないでこの機能は、Microsoft SQL Serverの将来のバージョンで削除されます。新しい開発作業でこの機能を使用しないでください。現在、この機能を使用しているアプリケーションを変更する予定です。

http://msdn.microsoft.com/en-us/library/ms187373.aspx

この記事では、SQL Server 2005に適用されますので、あなたはそのバージョンを使用している場合NOLOCKのサポートが存在します。

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

46

NOLOCKヒントの合法的な使用のためのテキストブックの例が報告され:将来もあなたのコードにするために、あなたのストアドプロシージャでこれを使用することができます(あなたはダーティリード使用することを決めたと仮定した場合)高更新OLTPデータベースに対してサンプリングします。

話題の例を挙げる。大規模な米国のハイストリート銀行が、都市レベルの最初の兆候を探している時間別のレポートを実行したい場合、ノーロッククエリは、都市ごとに現金預金と現金引き出しを合計した取引テーブルをスキャンできます。このようなレポートの場合、ロールバックされた更新トランザクションによって引き起こされるわずかな割合のエラーは、レポートの価値を低下させません。

13

単純な答え - SQLがデータを変更していないときで、(ロックによって)他の活動を妨げる可能性のあるクエリがあるときはいつでも。

特にクエリに1秒以上かかる場合は、レポートに使用するクエリについて検討する価値があります。

これは、OLTPデータベースに対して実行しているOLAPタイプのレポートがある場合に特に便利です。

質問する最初の質問は、 "なぜ私はこれについて心配ですか?"私の経験では、誰かが「何か試してみよう」モードに入っているときに、デフォルトのロック動作をしばしば行うことがありました。これは予期しない結果が起こりそうにないケースの1つです。あまりにもしばしばそれは時期尚早の最適化のケースであり、あまりにも簡単にアプリケーションに埋め込まれてしまうことがあります。なぜそれをやっているのか、どのような問題が解決しているのか、実際に問題があるのか​​を理解することは重要です。

147

質問が悪化しているものです:

  • デッドロック、または
  • 間違っ値はありますか?

金融データベースの場合、デッドロックは間違った値よりもはるかに悪いです。それは後ろ向きに聞こえるが、私のことを聞く。従来のDBトランザクションの例では、2行を1行から減算して別の行に追加します。それは間違いです。

財務データベースでは、取引取引を使用します。これは、各アカウントに1つの行を追加することを意味します。これらのトランザクションが完了し、行が正常に書き込まれることが最も重要です。

アカウントの残高を一時的に間違って取得することは大したことではなく、それは終わりの和解のためです。また、データベースからのコミットされていない読み込みのために、2つのATMが一度に使用されているため、アカウントの超過分が発生する可能性が非常に高くなります。

つまり、SQL Server 2005では、NOLOCKが必要としたバグのほとんどが修正されました。したがって、SQL Server 2000以前を使用している場合を除き、必要はありません。

さらに読書
Row-Level Versioning

+20

一時的に口座残高を取得するのは大したことではありませんか?その取引が当座貸越限度なしにATMから現金を引き出している場合はどうなりますか? – Learning

+10

@ラーニング:誰かがあなたのカードに請求する前にお金を30秒間取り出すとどうなりますか?すべてのコミュニケーションが瞬時になるまで、当座貸越は人生の事実になります。 –

+4

+1金融アプリケーション(どこでも、銀行だけではない)では、更新も削除もありません。誤った操作でもレコードを挿入することで訂正されます。この用語は英語で何ですか?それは "storno"ですか? Googleは私にこの質問に答えるのを助けなかった –

30

ないあなたが別の口座から資金を移すときのようにデータベーストランザクション(金融取引をラップしていない理由を確認してください - あなたがで取引の片側をコミットしていません-a-time - 明示的なトランザクションが存在する理由です)。たとえあなたのコードがビジネストランザクションに気付いたとしても、すべてのトランザクションデータベースは、エラーや障害が発生した場合に暗黙的なロールバックを行う可能性があります。私はこの議論があなたの頭上にあると思う。

ロックの問題がある場合は、バージョニングを実装してコードをクリーンアップします。

ロックは間違った値を返すだけでなく、ファントムレコードと重複を返します。

クエリが常により高速に実行されることはよくある誤解です。テーブルに書き込みロックがない場合は、何の違いもありません。テーブルにロックがあるとクエリが高速になることがありますが、ロックが最初に作成された理由があります。公平で

、ここでNOLOCKヒントは、ユーティリティにライブOLTPデータベースに対して長いクエリを実行する必要があります

1)前の2005 SQL Serverデータベースを提供することができる二つの特別なシナリオは、これが唯一の方法

かもしれあり

2)レコードをロックしてUIへの制御を戻し、リーダーが無期限にブロックされている、記述が不適切なアプリケーション。アプリケーションを修正できない場合(第三者など)、データベースが2005年以前か、またはバージョン管理が有効になっていない場合、Nolockが役立ちます。

+9

私はNOLOCKを記述していないコードを補うために使用すべきではないことに同意します。 しかし、私はあなたが実際に_データベース_トランザクションについて言及したことはないので、Johnathanに対するあなたの攻撃は不当だと思います。彼は、金融アプリケーションは通常、編集にレコードを許可しないことを指摘していました(明らかにいくつかの例外があります)。 あなたの資金移転の例では、勘定残高の値を借方/貸方エントリの代わりに_mutate_することが珍しいと言っています。 – chrnola

+17

異なる銀行のある口座から別の口座に資金が移転すると、どうなると思いますか?いくつかのuber-databaseは、Bank of AmericaのテーブルとWells Fargoのテーブルをロックします。いいえ。金融取引はそれぞれに書き込まれ、終わりのプロセスではすべてのレコードが一致することが確認されます。 –

9

レポートを生成する必要があるときは、WITH (NOLOCKを使用するのが理にかなっています。この時点で、データはほとんど変更されません&これらのレコードをロックしたくないです。

+2

あなたが現在の変更を気にしないなら、WITH(NoLOCK)が良いと思います。 –

47

残念ながら、コミットされていないデータを読み取るだけではありません。バックグラウンドでは、ページを2度読むことができます(ページ分割の場合)。そうしないと、ページが完全に見逃されることがあります。だからあなたの結果はひどく歪んでいるかもしれません。

Itzikベン・ガンの記事(sqlmag.com InstantDoc#92888 - http://www.sqlmag.com/article/sql-server/quaere-verum-clustered-index-scans-part-iii.aspx)チェックアウト:

「NOLOCKヒント(またはの 分離レベルを設定して:

は、ここに抜粋ですセッションでは、あなたが一貫性を期待していない SQL Serverを伝える) READ UNCOMMITTEDに、そう は保証はない。クマを念頭に「一貫性のないデータが」のみ あなたがuncommi見るかもしれないことを意味するわけではないことを ものの後でロールバックされた の変更、 の変更、またはトランザクションの中間の 状態のデータ変更。 また スキャンすべてのテーブル/インデックスデータをSQL Serverの は、スキャン位置を失う可能性があること、単純なクエリで、またはあなたが二回同じ行 を得るに終わるかもしれないことを意味します。 「

+4

もう少し下に、同じ行を2回取得する方法を説明します。 col1のクラスタード・インデックスが オプションIGNORE_DUP_KEYで一意索引として定義されるように、テーブルT1を再作成します。これは、重複値 がcol1に存在しないことを意味し、重複キー を挿入しようとすると、トランザクションが失敗せず、エラーが生成されます。 警告を生成します。**この奇妙なオプションを使用しないとおそらく、行を2回取得することについて心配する必要はありません。 – JanHudecek

+0

有線オプションを使用しなくても、dupe行を得ることができます。たとえば、クエリがユニークでないインデックスを利用する場合などです。しかし、これはnolock特有のことではありません。 – RMD

4

短い答え:

決して:私はWITH (NOLOCK)が削除見たい

長い答え:。

NOLOCKは、多くの場合、スピードアップする魔法の方法として利用されていますデータベースの読み取りは可能ですが、できる限りどこでも使用しないようにしています。

結果セットにはまだコミットされていない行が含まれている可能性があります。後でロールバックされることがよくあります。

エラーまたは結果セットは空でも、行がなくなったり、同じ行を複数回表示したりすることができます。

これは、他のトランザクションが読んでいるときに同時にデータを移動しているためです。

READ COMMITTEDは、複数のユーザーが同じセルを同時に変更する1つの列内でデータが破損するという問題を追加します。

その他の副作用もあり、最初に取得したい速度向上を犠牲にしています。

あなたがそれを取り除くことができる場所で使用することは問題ないと主張できますが、そのポイントは何ですか?私は、破損したデータが受け入れられる状況を考えることはできません。

これまでにNOLOCKを使用したことはありません。 (今まで)

+1

コミットされていないデータを読み取ることは、最終的な決定を変更しない場合は許容されます。たとえば、あなたが小売店が今後6ヶ月間にどれくらいのお金を投じるかを予測しようとしている場合、実際に3を買ったときにTammyが2本のペーパータオルを買ったことを見ても、将来のあなたの意見は変わりません。 –

+1

フィルタが含まれている場合、クエリを実行するとデータが不正確になります。フィルタに履歴データのみが含まれている場合、 'READ UNCOMITTED'を使用してもそれにはまったく影響しません。それがANSI標準に含まれていた理由があります。 –

+1

決して言わないでください。データを100%正確にする必要がある場合は、nolockを使用しないでください。私にとっては、これは通常そうではありません。ユーザーにデータを提示するとき、ユーザーがデータを操作するまでには、既に変更されている可能性がありますが、ロック競合は応答遅延の価値がありません。 – Perposterer

3

最も簡単な答えは簡単な質問です - あなたはあなたの結果が再現可能である必要がありますか?はいの場合、NOLOCKSは適切ではありません

再現性が必要ない場合、特にターゲットデータベースに接続するすべてのプロセスを制御できない場合は、nolockが便利です。

関連する問題