Wir haben einen Prozess, der einen Inventarbericht generiert. Auf der Clientseite teilt der Prozess eine konfigurierbare Anzahl von Arbeitsthreads auf, um einen Datenblock für den Bericht zu erstellen, der einem von vielen Speichern entspricht (möglicherweise Tausende, normalerweise Dutzende). Jeder Arbeitsthread ruft einen Webdienst auf, der eine gespeicherte Prozedur ausführt.
Der Datenbankprozess zum Verarbeiten jedes Blocks sammelt eine Reihe von Daten in einer # Temporären Tabelle. Am Ende jedes Verarbeitungsblocks werden die Daten in eine permanente Tabelle in tempdb geschrieben. Schließlich fordert ein Thread auf der Clientseite am Ende des Prozesses alle Daten aus der permanenten Tempdb-Tabelle an.
Je mehr Benutzer diesen Bericht ausführen, desto langsamer wird er. Ich habe die Aktivität in der Datenbank analysiert. An einem Punkt sah ich 35 separate Anfragen, die alle an einem Punkt des Prozesses blockiert waren. Alle diese SPIDs hatten in der Größenordnung von 50 ms Wartezeiten vom Typ LATCH_EX
auf Ressource METADATA_SEQUENCE_GENERATOR (00000010E13CA1A8)
. Eine SPID verfügt über diese Ressource, und alle anderen blockieren. Ich habe bei einer Websuche nichts über diese Warte-Ressource gefunden.
Die von uns verwendete Tabelle in Tempdb enthält eine IDENTITY(1,1)
Spalte. Warten diese SPIDs auf die Spalte IDENTITY? Mit welchen Methoden können wir die Blockierung reduzieren oder beseitigen?
Der Server ist Teil eines Clusters. Auf dem Server wird 64-Bit SQL Server 2012 Standard Edition SP1 unter 64-Bit Windows 2008 R2 Enterprise ausgeführt. Der Server verfügt über 64 GB RAM und 48 Prozessoren, die Datenbank kann jedoch nur 16 verwenden, da es sich um die Standardversion handelt.
(Beachten Sie, dass ich nicht begeistert bin von der Verwendung einer permanenten Tabelle in tempdb, um all diese Daten zu speichern. Eine Änderung wäre eine interessante technische und politische Herausforderung, aber ich bin offen für Vorschläge.)
UPDATE 23.04.2013
Wir haben einen Support-Fall mit Microsoft eröffnet. Ich werde diese Frage auf dem neuesten Stand halten, sobald wir mehr erfahren.
UPDATE 10.05.2013
Der SQL Server-Supporttechniker stimmte zu, dass die Wartezeiten durch die Spalte IDENTITY verursacht wurden. Durch das Entfernen der IDENTITY wurden die Wartezeiten beseitigt. Das Problem konnte in SQL 2008 R2 nicht dupliziert werden. Es trat nur unter SQL 2012 auf.
quelle
Antworten:
Angenommen, Sie können das Problem auf die Generierung von Identitätswerten beschränken (versuchen Sie, diese Spalte als Test zu entfernen), würde ich Folgendes empfehlen:
IDENTITY
Eigenschaft aus der Spalte in der endgültigen Tabelle.Wenn Sie also die Speicher-IDs 3 und 4 haben, erhalten Sie die endgültigen ID-Werte wie folgt:
Oder so ähnlich. Du hast die Idee.
Dadurch entfällt die Notwendigkeit, bei der
IDENTITY
Generierung zu serialisieren, während die Eindeutigkeit des Endergebnisses erhalten bleibt .Alternativ können Sie je nach Funktionsweise des Prozesses die endgültig berechneten ID-Werte in die # Temporary-Tabellen einfügen. Dann können Sie eine Ansicht erstellen, die
UNION ALL
sie zusammenfasst, sodass die Daten überhaupt nicht mehr kopiert werden müssen.quelle
IDENTITY
Spalte handelte. Wir haben es aus dem bereits breiten Clustered-Index entfernt und die Spalte vollständig entfernt. Es war nicht nötig. Danach verschwanden diese LATCH_EX-Wartezeiten. Wir konnten die Wartezeiten in SQL 2008 R2 nicht duplizieren. Das Problem trat nur auf SQL Server 2012 auf.IDENTITY
Werte generiert , neu geschrieben wurde, um das neue Sequenzgenerierungsmaterial zu verwenden, das 2012 neu war. Auf <2012 wird möglicherweise ein anderer Latch-Typ angezeigt. Wenn jedoch kein Perf-Problem aufgetreten ist, scheint dies der Fall zu sein eine Regression im Code. In jedem Fall ist das Entfernen derIDENTITY
Säule am sichersten.(Aktualisiert Februar 2019)
Dies ist ein alter Beitrag, der besagt, dass ich es endlich geschafft habe, Microsoft davon zu überzeugen, dass die Tatsache, dass dies geschieht, tatsächlich ein Defekt ist.
Update: MS hat den Fehler bestätigt und ihm die Fehlernummer 12628722 zugewiesen.
Ich hatte diesen Beitrag im vergangenen November 2018 gesehen, als wir nach dem Upgrade von SQL Server 2005 auf SQL Server 2017 zu leiden hatten. Eine 3,3-Millionen-Zeilentabelle, die 10 Sekunden für das Masseneinfügen benötigte, dauerte plötzlich 10 Sekunden Minuten auf Tabellen mit
Identity
Spalten.Es stellt sich heraus, dass dahinter zwei Probleme stehen:
Ich habe 4 Wochen gebraucht, aber kurz nach den Ferien bekam ich ein verspätetes Geschenk vom Weihnachtsmann - eine Bestätigung, dass das Problem tatsächlich ein Defekt war.
Es gibt einige mögliche Problemumgehungen, die wir gefunden haben, bis dies behoben ist:
Option (MaxDop 1)
in der Abfrage, um die Masseneinfügung wieder in einen serialisierten Plan umzuwandeln.Select Cast(MyIdentityColumn As Integer) As MyIdentityColumn
)SELECT...INTO
Update: Der Fix, den MS implementieren wird, besteht darin, diese Art von Inserts wieder auf die Verwendung eines
Serialized
Plans zurückzuführen. Dies ist für SQL Server 2017 CU14 geplant (keine Neuigkeiten zu anderen Versionen von SQL Server - sorry!). Bei der Implementierung muss das Trace-Flag 9492 entweder auf Serverebene oder über aktiviert werdenDBCC TraceOn
.quelle