1. ホーム
  2. sql-server

[解決済み] あるプロセスがデッドロックの犠牲となる原因

2022-09-18 10:07:41

質問

セレクトを使用した処理で、終了までに5~10分程度かかるものがあります。

現在、私は を使用していません。 NOLOCK を MS SQL データベースエンジンへのヒントとして使用します。

同時に、同じデータベースと同じテーブルに対して更新と挿入を行う別のプロセスもあります。

最初のプロセスが開始され、最近、メッセージで早々に終了するようになりました。

SQLEXCEPTION: トランザクションが他のプロセスとロック・リソースでデッドロックになり、デッドロックの犠牲者として選択されました。

この最初のプロセスは、同じ条件で他のサイトでも実行されていますが、データベースが小さいため、問題の select 文ははるかに短い時間 (30 秒程度のオーダー) で実行されます。 これらの他のサイトでは、デッドロックのメッセージは表示されません。 また、当初問題が発生しているサイトでは、このメッセージは出ませんでしたが、想定するに、データベースが大きくなったので、何らかの閾値を超えたのだろうと考えています。 以下は私の質問です。

  1. トランザクションの実行にかかる時間によって、関連するプロセスがデッドロックの犠牲者としてフラグを立てられる可能性が高くなる可能性はありますか。
  2. NOLOCK ヒントで select を実行した場合、問題は解消されますか?
  3. select 文の WHERE 句の一部としてチェックされる datetime フィールドが、遅いルックアップ時間を引き起こしているのではないかと思っています。 このフィールドに基づいたインデックスを作成することはできますか? それは望ましいことですか?

どのように解決するのですか?

<ブロッククオート

Q1:トランザクションの実行にかかる時間によって、関連するプロセスがデッドロックの犠牲者としてフラグが立てられやすくなる可能性はありませんか?

いいえ。SELECT は読み取りデータしか持っていなかったので犠牲者であり、したがって、トランザクションは より低いコスト に関連付けられているため、犠牲者として選ばれます。

<ブロッククオート

デフォルトでは、データベースエンジンはデッドロックの被害者として、トランザクションを実行している トランザクションを実行しているセッションを ロールバックに最もコストがかからない . また、ユーザは、デッドロック状態におけるセッションの優先順位を を使うことで、デッドロックの状況下でセッションの優先順位を指定することもできます。 SET DEADLOCK_PRIORITY ステートメントを使用します。 DEADLOCK_PRIORITY は、LOW、NORMAL、または HIGH に設定することができ、代わりに は、範囲 (-10 から 10) の任意の整数値に設定することができます。

Q2. NOLOCKヒントを指定してselectを実行すれば、問題は解消されるのでしょうか?

いいえ。いくつかの理由があります。

Q3. select文のWHERE句の一部としてチェックされるdatetimeフィールドが、検索時間が遅くなる原因になっているのではないかと思っています。このフィールドに基づいたインデックスを作成することは可能でしょうか。それは望ましいことでしょうか?

おそらく。デッドロックの原因は、データベースのインデックスの不備である可能性が非常に高いです。10分クエリは、このような狭い条件では許容されますが、あなたのケースでは100%確実なのは、次のとおりです。 ではありません。 許容されません。

99% の信頼性で、デッドロックの原因は更新と競合する大規模なテーブルスキャンであると断言します。まず デッドロック グラフ をキャプチャして、原因を分析します。データベースのスキーマを最適化する必要がある可能性が非常に高いです。変更を行う前に、このトピックを読んでください。 インデックスの設計 とそのサブトピックを読んでください。