Wir haben eine Datenbank für ein Produkt, das schwer zu beschreiben ist. Wir haben gerade einen neuen Server mit einer SSD gekauft, um zu helfen. Zu unserer Überraschung waren die Einfügungen nicht schneller als auf unserer alten Maschine mit viel langsamerer Lagerung. Beim Benchmarking haben wir festgestellt, dass die E / A-Rate des SQL Server-Prozesses sehr niedrig war.
Zum Beispiel habe ich das Skript auf dieser Seite ausgeführt , mit der Ausnahme, dass ich ein BEGIN TRAN und ein COMMIT um die Schleife hinzugefügt habe. Bestenfalls konnte ich sehen, dass die Festplattenauslastung 7 MB / s erreichte, während die CPU 5% kaum berührte. Auf dem Server sind 64 GB installiert, und es wird 10 verwendet. Die Gesamtlaufzeit betrug 2 Minuten und 15 Sekunden für den ersten Aufruf bis zu einer Minute für nachfolgende Aufrufe. Die Datenbank wird einfach wiederhergestellt und war während des Tests inaktiv. Ich ließ den Tisch zwischen jedem Anruf fallen.
Warum ist so ein einfaches Skript so langsam? Die Hardware wird kaum genutzt. Sowohl dedizierte Festplatten-Benchmarking-Tools als auch SQLIO zeigen an, dass die SSD sowohl beim Lesen als auch beim Schreiben mit Geschwindigkeiten von über 500 MBit / s ordnungsgemäß funktioniert. Ich verstehe, dass zufällige Schreibvorgänge langsamer sind als sequentielle Schreibvorgänge, aber ich würde erwarten, dass eine einfache Einfügung in eine Tabelle ohne gruppierte Indizierung viel schneller ist.
Letztendlich ist unser Szenario viel komplexer, aber ich habe das Gefühl, dass ich zuerst einen einfachen Fall verstehen muss. Kurz gesagt, unsere Anwendung löscht alte Daten, kopiert neue Daten mithilfe von SqlBulkCopy in Staging-Tabellen, filtert sie und kopiert die Daten schließlich mithilfe von MERGE und / oder INSERT INTO (je nach Fall) in die endgültigen Tabellen.
-> BEARBEITEN 1: Ich habe die Prozedur von Martin Smith befolgt und folgendes Ergebnis erhalten:
[Wait Type] [Wait Count] [Total Wait (ms)] [T. Resource Wait (ms)] [T. Signal Wait (ms)]
NETWORK_IO 5008 46735 46587 148
LOGBUFFER 901 5994 5977 17
PAGELATCH_UP 40 866 865 1
SOS_SCHEDULER_YIELD 53279 219 121 98
WRITELOG 5 145 145 0
PAGEIOLATCH_UP 4 58 58 0
LATCH_SH 5 0 0 0
Ich finde es seltsam, dass NETWORK_IO die meiste Zeit in Anspruch nimmt, wenn man bedenkt, dass kein Ergebnis angezeigt und keine Daten an einen anderen Ort als in die SQL-Dateien übertragen werden müssen. Umfasst der Typ NETWORK_IO alle E / A?
-> BEARBEITEN 2: Ich habe eine 20-GB-RAM-Disk erstellt und von dort aus eine Datenbank gemountet. Die beste Zeit, die ich auf der SSD hatte, war 48 Sekunden, mit der RAM-Disk ging es auf 37 Sekunden zurück. NETWORK_IO ist immer noch das größte Warten. Die maximale Schreibgeschwindigkeit auf die RAM-Disk betrug etwa 250 MB / s, während sie mehrere Gigabyte pro Sekunde verarbeiten kann. Es wurde immer noch nicht viel CPU verbraucht. Was hält also SQL davon ab?
NETWORK_IO
könnte von der 3 Millionen „1 Zeile (n) betroffen“ sein , um Nachrichten zurück gesendet werden. Haben Sie versucht SET NOCOUNT ON
, dem Skript etwas hinzuzufügen ?
EE_WaitStats*.xel
sodass alte Ihre Ergebnisse verunreinigen.
SET NOCOUNT ON
.