Ich importiere eine große Datenmenge in eine leere Datenbank und habe vor dem Start alle nicht eindeutigen nicht gruppierten Indizes deaktiviert, um festzustellen, ob ich die Leistung des Imports verbessern kann.
Jetzt möchte ich die Indizes wieder aktivieren und frage mich, ob ich etwas tun kann, um dies zu optimieren.
Es müssen> 100 Tabellen und fast 2.000 Indizes neu erstellt werden. Die Datenbank ist 200 GB groß.
Der Schlüsselabschnitt des Skripts, das ich ausführe, ist folgender:
declare c_toggle_index cursor FORWARD_ONLY READ_ONLY for
select 'alter index ' + QUOTENAME(i.name) + ' on ' + o.name + ' rebuild'
from sys.indexes as i
Inner Join sys.objects o
On o.object_id = i.object_id
Where o.is_ms_shipped = 0
And i.index_id >= 1
and i.type > 1
and i.is_disabled = 1
Ich habe überlegt, ONLINE = OFF für die Anweisung alter index zu setzen, aber als die Indizes deaktiviert beginnen, war ich mir nicht sicher, ob diese Einstellung Auswirkungen haben würde. Ich habe auch überlegt, SORT_IN_TEMPDB = ON zu setzen, aber da sich die Tempdb-Dateien auf demselben Laufwerk befinden wie die MDF-Dateien der Datenbanken, habe ich angenommen, dass dies auch keinen Vorteil hat.
Beim Ausführen des Wiederherstellungsskripts habe ich festgestellt, dass ich viele CXPACKET-Wartetypen habe. Ich verstehe nicht wirklich, warum das so ist oder ob es ein Problem ist, das ich ansprechen sollte.
Ein letzter Punkt, der relevant sein kann: Mein gesamter Server ist derzeit inaktiv, abgesehen von diesem Import von Daten in die Datenbank. Es gibt keine andere Benutzeraktivität, die berücksichtigt oder befürchtet werden muss. Mein einziges Anliegen ist es, die Daten in kürzester Zeit in die Datenbank zu importieren.
quelle
CXPACKET
Wartezeiten: Der Index erstellt sich selbst neu. Scan-Indizes (sogar der Index, der neu erstellt wird ), und diese Scans können Parallelität verwenden. Sie sollten sich keine Sorgen um diese Wartezeiten machen - die Parallelität hilft wahrscheinlich.Antworten:
Um in diesem Szenario eine optimale Importleistung zu erzielen, sind drei Dinge erforderlich:
Minimale Protokollierung
Um minimal protokollierte Einfügungen in eine leere Clustertabelle ohne nicht gruppierte Indizes zu erzielen, sind folgende Voraussetzungen erforderlich:
SIMPLE
oder dasBULK_LOGGED
DatenbankwiederherstellungsmodellTABLOCK
undORDER
Hinweise)Randnotiz:
Nicht gruppierte Indizes separat erstellen
Dies hat folgende Vorteile:
CREATE INDEX
wird minimal protokolliert, wenn das Wiederherstellungsmodell nicht vorhanden istFULL
Vermeiden physischer Lesevorgänge
Im Idealfall werden die zu importierenden Daten auf einem separaten Computer oder zumindest auf einem anderen physischen Speicher als dem zum Hosten der Datenbank verwendeten gespeichert.
Der Datenbankserver sollte über genügend Speicher verfügen, um die größte Basistabelle im Cache zu speichern, und über genügend Speicherplatz für Sortiervorgänge verfügen, die beim Erstellen von nicht gruppierten Indizes erforderlich sind.
Ein gutes Muster besteht darin, die Basistabelle schnell zu laden (minimal protokollierte Clustered-Index-Last) und dann alle nicht-Clustered-Indizes für diese Tabelle zu erstellen, während ihre Datenseiten noch zwischengespeichert sind.
Die Frage beschreibt einen Prozess, bei dem zuerst Basistabellen geladen und dann nicht gruppierte Indizes erstellt werden. Die Cursordefinition verwendet keine
ORDER BY
Klausel , um nicht gruppierte Indexbuilds, die auf derselben Tabelle basieren, zumindest zu gruppieren.Das wahrscheinliche Ergebnis ist, dass Datenseiten für verschiedene Tabellen wiederholt in den Cache eingelesen und dann verworfen werden, wenn nicht gruppierte Indizes in einer nicht deterministischen Reihenfolge erstellt werden.
Die Kosten für wiederholte physische Lesevorgänge dominieren vollständig die Vorteile einer minimalen Protokollierung, die durch die separate Erstellung nicht gruppierter Indizes erzielt wird. Dies erklärt, warum Sie festgestellt haben, dass das Laden von Tabellen mit vorhandenen Indizes schneller ist (da alle nicht gruppierten Indizes für eine bestimmte Tabelle beibehalten werden, bevor Sie mit der nächsten Tabelle fortfahren).
Zusammenfassung
Der Importvorgang sollte überarbeitet werden, um jeweils eine Tabelle in großen Mengen zu laden. Dies bedeutet, dass Sie die Tabelle laden und alle nicht gruppierten Indizes erstellen, bevor Sie mit dem nächsten fortfahren. Die SQL Server-Instanz sollte über genügend Speicher verfügen, um die größte Tabelle aufzunehmen und gleichzeitig die größte nicht gruppierte Indexsortierung durchzuführen.
Sie können auch versuchen, TF 610 zu aktivieren, bevor Sie die Daten in Tabellen mit bereits vorhandenen Cluster-Indizes laden. Dies ist normalerweise nicht so schnell wie die vorherige Methode, kann aber schnell genug sein.
Weitere Informationen finden Sie im Folgenden:
Das Handbuch zum Laden von Daten
Vorgänge, die minimal protokolliert werden können
quelle