Es ist eine Situation , in Ihrem aktuellen Setup , das auf einen automatische Erhöhung Schlüssel (bezogen würde / könnte eine Verlangsamung verursachen IDENTITY
, GETDATE()
, NEWSEQUENTIALID()
): unter hohen Nebenläufigkeit INSERT - Operationen, kann es Streit zu platzieren Zeilen auf derselben Seite verbunden sein. Dies wird als "Hotspot" bezeichnet und ist einer der wenigen Nachteile beim automatischen Inkrementieren von Werten, da diese von Natur aus direkt nebeneinander liegen.
Ich fand widersprüchliche Informationen darüber, ob das "Hotspot" -Problem noch relevant war oder nicht:
Zu diesen drei Links sind einige interessante Dinge zu beachten:
- Einige der Antworten in dieser DBA.SE-Frage erwähnen die beiden anderen obigen Links. @Gbn weist darauf hin, dass der Artikel, der zeigt, dass das Hotspot-Problem weiterhin besteht, "einen nicht eindeutigen Clustered-Index für TranTime verwendet. Dazu muss ein Eindeutiger hinzugefügt werden. Dies bedeutet, dass der Index nicht streng monoton ansteigt (und zu breit ist). . "
- Technisch gesehen existiert der Eindeutigkeitswert (und damit der von diesem verborgenen Feld belegte Platz) nur in Zeilen, die nicht eindeutig sind. Daher ist es möglich, Zeilen einzeln in einem einzelnen Thread hinzuzufügen, und es wären eindeutige Werte, die ständig zunehmen würden, und es gäbe keinen eindeutigen Wert.
- Bei diesem Test wurden jedoch 400 gleichzeitige Verbindungen simuliert, bei denen der Testprozess 200 Mal ausgeführt wurde (ich nehme an, pro Verbindung). Daher ist es sehr wahrscheinlich, dass mehrere dieser INSERT-Vorgänge in derselben Millisekunde ausgeführt wurden und denselben Wert von erhalten haben
GETDATE()
.
- Ergo mag es angebracht sein, diesen bestimmten Test als ungültig in Bezug auf "Treten Hotspots auf, wenn ein eindeutiger, immer größer werdender Wert als Clustered-Index verwendet wird?" Auszuschließen, aber dieser Test könnte hier von hoher Relevanz sein. Die Beschreibung des Index in dieser Frage lautet, dass er "einen Clustered Key (DateTime) hat, der über GETDATE () erstellt wird". Es scheint sicher anzunehmen, dass der Index in dieser Frage nicht eindeutig ist (insbesondere wenn es sich nur um dieses eine DATETIME-Feld handelt). Und er hat 400 gleichzeitige Verbindungen getestet, während diese Frage besagt, dass es ungefähr 500 gleichzeitige Verbindungen gibt? Das klingt nach einem sehr ähnlichen Setup. Es ist daher sinnvoll, dasselbe Skript "SQL Server Perf Stats" auszuführen, um festzustellen, ob auch ähnliche LATCH-Konflikte auftreten.
Eine andere zu berücksichtigende Sache ist, dass die Indexpflege (REBUILD / REORGANIZE) zwar nicht automatisch erfolgt, die Statistik jedoch aktualisiert wirderfolgt automatisch (bei einer gleitenden Skala von% der geänderten Zeilen). Dies ist die Standardeinstellung für Datenbanken, es sei denn, Sie setzen "Auto Update Statistics" auf "false". Es gibt eine verwandte Option, die standardmäßig "false" ist und "Statistiken automatisch aktualisieren", die während dieses automatischen Aktualisierungsvorgangs keine Blockierung verursacht. Die durch die automatische Aktualisierung der Statistik verursachte Blockierung tritt während der Planerstellung für alle Pläne auf, die Informationen zu der bestimmten Statistik benötigen, die zu diesem Zeitpunkt aktualisiert wird. Mit der Option "Statistiken asynchron automatisch aktualisieren" kann das Abfrageoptimierungsprogramm Statistiken verwenden, von denen bekannt ist, dass sie veraltet sind und aktualisiert werden. Sobald die Statistiken aktualisiert sind, werden sie verwendet.
Eine andere Sache, die eine periodische Verlangsamung von INSERTs (sowie einiger UPDATEs) verursachen kann, ist das automatische Wachstum der Daten- und Protokolldateien. Offensichtlich wächst das Trans-Log auch bei DELETE-Operationen. Für INSERT-Vorgänge und UPDATE-Vorgänge, bei denen die neue Zeile größer als die vorherige Version dieser Zeile ist, müssen möglicherweise neue Seiten zugewiesen werden, wenn auf der entsprechenden Seite kein Platz mehr vorhanden ist. Wenn kein Speicherplatz mehr zum Zuweisen der Seite verfügbar ist, versucht SQL Server, die Datendatei zu vergrößern (sofern dies nicht deaktiviert wurde). Während die Daten- (oder Protokoll-) Datei vergrößert wird, werden Vorgänge für diese Datei blockiert. Aus diesem Grund ist es wichtig, die Datendateien richtig zu dimensionieren, damit die darin enthaltenen Tabellen wachsen können, ohne dass eine automatische Vergrößerung erforderlich ist oder zumindest nicht häufig.
Der Vollständigkeit halber gibt es das CHECKPOINT
Verhalten, auf das @Remus in einer anderen Antwort auf diese Frage hingewiesen hat.
Es ist zu beachten, dass Seitensplits keine Funktion von DML-Operationen im Allgemeinen oder unter hoher Last sind. Sie sind eine Funktion von:
- (die Reihenfolge, in der Daten eingefügt werden, ODER
- eine Erhöhung der Zeilengröße für aktualisierte Daten) UND
- ob auf der entsprechenden Seite Platz für eines dieser Ereignisse vorhanden ist oder nicht
Single-Threaded-INSERT-Operationen eines Schlüssels mit automatischer Inkrementierung sollten niemals zu einer Seitenteilung führen. INSERT-Operationen mit mehreren Threads eines Schlüssels mit automatischer Inkrementierung könnten (glaube ich) in einem hochvolumigen, gleichzeitigen INSERT-Szenario in der falschen Reihenfolge ausgeführt werden (und daher möglicherweise einen Seitensplit verursachen), je nachdem, ob der Scheduler (das SQL-Betriebssystem) Multithreading) würde so etwas wie das Zuweisen des Werts aus dem tun, GETDATE()
aber dann diesen Thread in die Warteschleife stellen, während ein anderer eingefügt wird, um dann für die eigentliche Einfügung zu diesem zurückzukehren. Ich habe das "Wenn" hervorgehoben, da ich nicht bewiesen habe, dass dies geschieht. Und UPDATE-Vorgänge sollten auf keinem Volume Seitenaufteilungen verursachen, wenn die Zeilengröße nicht zunimmt.