Die beiden Abfragen, die den Deadlock verursachen, sind SELECT
unten (process id="process3980de4558"
):
select @existing = team_it_cube_attr_05 from tbl_Ref_Attr_Prod_Team where prod_id = @rec_key
Und das UPDATE
Abfrage unten (process id="process386ed48188"
):
UPDATE D
SET D.team_rss_attr_01 = LEFT(S.mkt_prodchar_13,25)...
Die <resource-list>
Abschnitt notiert das SELECT
Die Abfrage besaß eine exklusive (X) Sperre auf einer Seite und versuchte, eine Intent-Shared (IS)-Sperre auf einer anderen Seite zu erwerben, während sie Daten las. Das UPDATE
Die Abfrage besaß bereits eine IS-Sperre und versuchte, eine X-Sperre auf einer Seite zu erwerben, um die Aktualisierung durchzuführen.
Angesichts der Verknüpfung mit dieser Tabelle:
...from tbl_Ref_Attr_Prod_Team where prod_id = @rec_key...
...INNER JOIN tbl_Ref_Attr_Prod_Team D ON D.prod_key=P.prod_key...
Die SELECT
Abfrage besitzt bereits eine exklusive Sperre. Dies bedeutet wahrscheinlich, dass es Teil einer größeren Transaktion ist, die bereits ein UPDATE
durchgeführt hat in einer vorherigen Abfrage. Sperren von früheren Abfragen werden beibehalten, um die Datenintegrität während der Transaktion zu bewahren (abhängig von Transaktionsisolationsstufe
).
Das UPDATE
Abfrage muss die Tabelle tbl_Ref_Attr_Prod_team
lesen . Es erwirbt beim Lesen von Daten Intent-Shared-Locks auf Seiten und Zeilen. Wenn das UPDATE
Abfrage die übereinstimmenden Zeilen findet, wird sie versuchen, die IS-Sperren in X-Sperren umzuwandeln. IS-Sperren sind nicht mit X-Sperren kompatibel. Da die SELECT
Abfrage hat bereits eine IS-Sperre auf einer oder mehreren dieser Seiten, die Abfragen blockieren sich gegenseitig.
Eine mögliche Ursache wären fehlende Indexe auf tbl_Ref_Attr_Prod_team.prod_key
. Ohne einen Index für diese Spalte wird das UPDATE
Die Abfrage scannt alle Zeilen in der Tabelle tbl_Ref_Attr_Prod_team
.
Auch wenn ein Index auf prod_key
existiert , wenn die Tabelle eine kleine Anzahl von Zeilen enthält, entscheidet SQL Server möglicherweise, dass die Leistung besser wäre, wenn die Abfrage die gesamte Tabelle scannen würde, anstatt den Index zu suchen. Das Aufzeichnen des Abfrageplans beim Auftreten des Deadlocks würde diese Theorie bestätigen.
Wir stoßen regelmäßig auf kleine Tabellen-Deadlocks, wenn wir neue Datenbanken bereitstellen. Anfangs sind die Tabellen winzig, und Tabellenscans verursachen alle Arten von Deadlocks. Später, wenn die Tabellen größer sind, übersteigen die berechneten Kosten für das Scannen der Tabelle die Kosten für das Suchen des Index, und die Deadlocks treten nicht mehr auf. In Testumgebungen, in denen die Anzahl der Zeilen immer kleiner wird, haben wir auf die Verwendung von FORESEEK
zurückgegriffen und WITH INDEX
Hinweise zum Erzwingen von Indexsuchen anstelle von Scans. Wir freuen uns darauf, Abfragepläne über die Abfragespeicherfunktion von SQL Server 2016 erzwingen zu können.