Einfügen und Aktualisieren und Auswählen tausende Male pro Sekunde

7

Ich habe eine Tabelle, die innerhalb einer Sekunde tausende Male eingefügt, aktualisiert und ausgewählt wird. Ich habe jedoch Deadlock-Probleme.

  1. Die Datenbank verfügt über 2-5 gleichzeitige 1000+ Zeileneinfügungen mit Linq to Sql.
  2. 40 Mal pro Sekunde gibt es auch eine select-Anweisung aus dieser Tabelle. Wenn eine Bedingung erfüllt ist (in 95% der Fälle), erfolgt eine Aktualisierung mit ähnlichem Code:

    Prozedur erstellen AccessFile (@code, @admin) AS

    deklarieren Sie @id int, @access datetime, @file string

    Wählen Sie @ id = Id, @accessed = abgerufen, @file = Datei aus Dateien, in denen code = @code

    IF @admin <> 0 IF @accessed ist null begin

    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

    Aktualisieren Sie den Dateisatz access = getdate (), wobei id = @id

    SET TRANSACTION ISOLATION LEVEL READ COMMITTED

    Ende

    Wählen Sie @id als ID, @file als Datei

Es scheint, als ob es die Aktualisierungen sind, die mit den Einfügungen in Konflikt stehen und die Deadlocks verursachen.

Das Beispiel ist eine 1 zu 1 mit der gespeicherten Prozedur, nur der Unterschied sind die Namen. Nehmen Sie die 1 und 2 an, unabhängig von den Namen der gespeicherten Prozeduren.

Jeremy Boyd
quelle
1
Können Sie uns Ihre Tischstruktur geben? Spalten, Schlüssel, Indizes?
Eric Humphrey - Lotsahelp
ist es SQL Server? Orakel? MySQL?
Eiefai
@eric - Sehr einfach: ID (PK; bigint), Code (Index, eindeutig; varchar (16)), Zugriff (Datum / Uhrzeit), Erstellt (Datum / Uhrzeit), Datei (varchar (48))
Jeremy Boyd
@ Eiefai - MSSQL 2008 R2
Jeremy Boyd
2
In dieser Frage erhalten Sie hier einen Hinweis: dba.stackexchange.com/questions/126/… Es geht um Deadlocks und wie man sie fängt und behandelt.
Marian

Antworten:

2

Ändern Sie die Updates, um WITH (ROWLOCK) zu verwenden. Dadurch werden die Sperren von Seitenebene auf Zeilenebene reduziert. Sie können das gleiche auch bei den Einsätzen versuchen.

mrdenny
quelle
Ich habe sowohl die Einfügungen als auch die Aktualisierungen für (Rowlock) aktualisiert, aber die Anzahl der Deadlocks wurde nicht verringert. Wenn ich die Einfügungen töte (schalte den Knopf aus, mit dem unsere Benutzer einfügen können), verschwinden die Deadlocks.
Jeremy Boyd
2
Versuchen Sie es mit der Snapshot-Isolationsstufe. Ich werde die gleichen Änderungen am Code vornehmen, der die Einfügungen vornimmt (es sei denn, sie werden von einer gespeicherten Prozedur durchgeführt). Es könnte helfen, aber es wird die Tempdb-Nutzung um ein Vielfaches erhöhen. Übrigens: Wenn Sie die Isolationsstufe so ändern, dass sie für ein Update nicht festgeschrieben ist, wird dies nichts bewirken. Ich gehe davon aus, dass die ID-Spalte Ihr Clustered-Index ist.
Mrdenny
2

Sie können es auch zu Beginn des Prozesses versuchen und die Isolationsstufe auf SNAPSHOT setzen. Weitere Informationen finden Sie unter: http://msdn.microsoft.com/en-us/library/ms173763.aspx

Für die Zeilenversionierung fallen in tempdb einige Kosten an.

Eric Humphrey - Lotsahelp
quelle
1
Das erinnerte mich an diesen Beitrag über das Einstellen der Datenbank auf eine Snapshot-Ebene. Codinghorror.com/blog/2008/08/deadlocked.html
Beth Whitezel
0

Ich würde die Anwendungen so umgestalten, dass Zeilen in Stapeln gespeichert werden. Normalerweise funktionieren Stapel von 500-1000 Zeilen gut für mich, aber Sie müssen Ihre eigenen Tests ausführen. Bevor ich einen Stapel speichere, serialisiere ich meine Stapelaktualisierungen mit sp_getapplock.

Sicherlich verlangsamt diese Serialisierung die Änderungen ein wenig, aber das Speichern in Stapeln gleicht dies mehr als aus, sodass dies insgesamt viel schneller funktioniert, als wenn Zeilen nacheinander gespeichert werden.

Außerdem würde ich meine Auswahl mit der SNAPSHOT-Isolationsstufe ausführen, damit sie durch Änderungen nicht blockiert werden.

Wenn Sie dies getan haben, haben Sie möglicherweise überhaupt keine Deadlocks - wir haben keine Deadlocks in unserem Mischlastsystem, und Sie auch.

Viel Glück!

AK
quelle