Server一つのテーブルにクラスタ化インデックスと非クラスタ化インデックスが貼られている場合に、同一テーブル内のインデックス間で発生するデッドロックについて検証してみました。以下のようなテーブルにテストデータを用意します。[PRIMARY]適当なテストデータを投入しておきます。デッドロックさせるインデックスとして以下インデックスを準備します。[col4])GOデッドロック用のクエリを実行UPDATE側のクエリでは、クラスタ化インデックスを使って更新するクエリを実行します。その際、更新対象の項目は付加列インデックスで使用している列を更新します。1ENDこのUPDATE側のクエリでは次の実行プランからもわかる通り、クラスタ化インデックスを排他ロックにて参照し、付加列インデックスを更新します。lookupでクラスタ化インデックスへの参照が発生するようなクエリを実行します。lookupを使用してクラスタ化インデックスから列の参照していることがわかるかと思います。lookupを使ってしまうパターンなどインデックスの仕組みについては以下をご参照ください。memorandom-nishi.hatenablog.jpデッドロック発生時のロック状況を確認してみると、UPDATE側は排他ロック、SELECT側は共有ロックを取る際にデッドロックが発生していることがわかります。(RECOMPILE)実際にインデックス間でデッドロックが発生した場合のデッドロックグラフを確認してみると、お互いのインデックスのロック解放待ち状態となっていることが確認できるかと思います。#デッドロックグラフはデフォルトで取得されている拡張イベント「system_health」から確認できます。<UPDATE側>UPDATE側クエリがクラスタ化インデックスの排他ロックを獲得UPDATE側クエリが非クラスタ化インデックスの排他ロック獲得待ち<SELECT側>SELECT側クエリが非クラスタ化インデックスの共有ロックを獲得SELECT側クエリがクラスタ化インデックスの共有ロック獲得待ちまた、今回はキーロックのデッドロック時の情報としてwaitresourceの値からどのデータでデッドロックが発生してしまったか確認することができます。拡張イベントのsystem_healthのSSMSにて開き、カラムの上で右クリック、「列の選択」を選択します。「選択した列」に「xml_report」を追加します。xml_reportを列として追加できたら、name列が「xml_deadlock_report」であるレコードのxml_report列をダブルクリックします。デッドロック情報がxml形式で確認できるため、xmlの「waitresource」のカッコ()の値を確認します。カッコ()の値を使って、以下クエリで検索します。'(de42f79bc795)'検索結果から、デッドロック時のキーが確認できます。同一テーブル内のインデックス間デッドロックの解決策このようなインデックス間のデッドロックが発生する場合の解決策としては以下が考えられるかと。SNAPSHOTにするただし(2)は、参照時に直接共有ロックをかけないものの、その分tempdbにおける負荷が高くなることはデメリットとなることは考慮すべきかと思います。ロックやトランザクション分離レベルについてはこちらを参照いただければ。Server2016】dm_exec_input_bufferについて月別アーカイブはてなブログをはじめよう!utiowaさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。