sql >> データベース >  >> RDS >> Sqlserver

この SQL Server クエリがデッドロックになるのはなぜですか?

    • プロセス 9196a8 には、X モードでページ 151867 スロット 174 があり、S モードでページ 140302 スロット 31 が必要です
    • プロセス 88b5b8 には、X モードでページ 140302 スロット 31 があり、S モードでページ 151867 スロット 174 が必要です
    • isolationlevel="repeatable read (3)" の下で実行される 2 つの削除

    そのため、デッドロックはテーブルのベース ヒープで発生します (キー ロックではなく RID ロックは、Btree ではなくヒープを意味します)。分離レベルが高い (xact 名から判断すると、DTC が原因である可能性が高い) ため、RCSI 設定は無関係になります。

    列 PARTYEXTERNALREF および PARTYTYPE はどの型ですか?渡されるパラメーターは NVARCHAR (つまり Unicode) であり、列が VARCHAR (つまり Ascii) の場合は、データ型の優先順位 NC インデックスは使用されません。関連するテーブル スキャンと、使用中の高い分離レベルのため、デッドロックはほとんど避けられません。

    解決策は、@P0 と @P1 に VARCHAR タイプのパラメーターを使用して、NC インデックスを利用してテーブル スキャンを回避することです。

    パラメータがすでに VARCHAR 型であり、NC でのシークが使用されていることを実行計画から確認できる場合、私の最初の質問は else です。 削除ステートメント以外のトランザクションは実行されていますか?

    ところで、あなたは NC インデックスの名前しか与えていませんが、私は (PARTYEXTERNALREF, ISCOUNTERPARTY, PARTYID) にあると思います .

    更新

    あなたのコメントは列が であると言っているので NVARCHAR の場合、テーブル スキャン仮説はおそらく間違っています。調査が必要なデッドロックを引き起こす可能性がさらに 3 つあります。

    • DELETE の前にトランザクションによって実行されるその他のステートメント (これが最も可能性が高い)
    • デッドロックに関係する 2 つの DELETE ステートメントによって選択された行の重複
    • ハッシュ衝突

    最初の 2 つの仮説については、今すぐできることは 1 つだけです (それらが正しいかどうかを調べてください)。最後の 1 つについては、それを検証する方法を説明できますが、簡単ではありません。発生する可能性は低く、証明するのは少し難しいですが、可能です。デッドロック ケース (添付の XML) として知られているので、調査のベースとして使用してください:

    • データベース のある時点のコピーを復元します。 2011-09-02T19:00:29.690
    • DBCC TRACEON(3604,-1) を実行します
    • DBCC PAGE (<restored db id>, 1, 151867, 3) スロット 174 の値を調べます
    • DBCC PAGE(, 1, 140302, 3)` を使用して、スロット 31 の値を調べます
    • run SELECT %%lockres%% FROM PARTIES WHERE PARTYEXTERNALREF = ... AND ISCOUNTERPARTY='N' and PARTYID=... 上記で読み取った値を渡します
    • 結果のロック ハッシュ値を比較します。一致する場合は、ハッシュの衝突があり、これがデッドロックの原因です。



    1. 行、ページ、テーブルのロックとは何ですか?そして、それらが取得されたとき?

    2. PDOは生のクエリをMySQLに送信し、Mysqliは準備されたクエリを送信します。どちらも同じ結果を生成します

    3. phpセッションとmysqlの速度

    4. 日付の最大値を持つ3つの関連付けテーブルのフィールド値を取得するにはどうすればよいですか?