Ich habe eine große Tabelle, die Zeilenanzahl der Tabelle beträgt mehr als 3 Milliarden, der Datenraum für diese Tabelle beträgt ca. 120 GB.
Und Intel Xeon CPU E5645 bei 2,4 GHz (2 Prozessoren), 24 CPUs, 64 G Speicher, 64 Bit Windows Server 2008 R2 Enterprise.
ich renne
create unique clustered index MyTable_IXC on tblFactFoo(barKey) on [PRIMARY]
Es dauerte jedoch mehr als 6 Stunden (tatsächlich wurde nach 6 Stunden ein Fehler beim doppelten Schlüssel gemeldet).
Beim Ausführen betrug die CPU weniger als 10% und die Festplatten-E / A weniger als 20 MB / s, normalerweise etwa 15 MB / s. Ich frage mich, wie die Leistung beim Erstellen eines Clustered-Index mit solch leistungsstarker Hardware verbessert werden kann.
sql-server
performance
sql-server-2008-r2
clustered-index
Aaron Bertrand
quelle
quelle
Antworten:
Sie müssen sich den Wartetyp ansehen, wenn die Abfrage ausgeführt wird. Wahrscheinlich benötigen Sie schnellere Festplatten, da das Erstellen eines Index für eine so große Tabelle zu massiven Lese- und Schreibvorgängen führen wird.
Kurz gesagt, Sie müssen die 120-Gig-Tabelle lesen, sie nach dem Clustering-Schlüssel sortieren (was dazu führen wird, dass Tempdb mit einer Menge Geld verschüttet wird, wahrscheinlich 100 Gigs in Tempdb) und dann den Clustered-Index in die Datenbank schreiben verursacht 120 Gigs von Schreibvorgängen.
Darüber hinaus müssen alle nicht gruppierten Indizes in der Tabelle gleichzeitig neu erstellt werden, sodass auch alle Indizes gelesen und neu geschrieben werden müssen (zusammen mit dem gesamten Speicherverlust, der mit der Neuerstellung der nicht gruppierten Indizes verbunden ist).
Sie können die Dinge beschleunigen, indem Sie die Nicht-Clusterd-Indizes deaktivieren und sie dann manuell erstellen, nachdem der Clustered-Index neu erstellt wurde. Sie sollten sicherstellen, dass Endbenutzer das System nicht berühren können, während die nicht gruppierten Indizes erstellt werden, da ihre Abfrageleistungen bis zur Erstellung der nicht gruppierten Indizes schrecklich sind.
Angenommen, Sie können die häufig verwendeten Indizes erstellen, dann die Benutzer wieder einlassen und dann die anderen Indizes online erstellen, damit die Benutzer arbeiten können.
Egal, was Sie in einem WIRKLICH langen Wartungsfenster sehen, in dem Sie die Festplatten so hart wie möglich zuschlagen.
quelle
Hier sind einige Dinge zu bewerten:
SORT_IN_TEMPDB
. Dies kann die E / A-Muster drastisch verbessern (mehr sequentielle E / A und weniger Fragmentierung im endgültigen Index).Oder laden Sie die Daten zunächst richtig sortiert. Dann müssen Sie überhaupt keinen Index erstellen. Dies hat gewisse Nachteile, ist aber erwägenswert. Die bestmögliche Lösung wäre das Laden in einen partitionierten Clustered-Index unter Verwendung des
ORDER
Hinweises zum Massenladen. Ein Massenimportstrom pro Partition und eine Partition pro CPU oder pro physischer Festplatte.quelle
Wie ich das persönlich machen würde:
quelle
Jedes Mal, wenn Sie einen Clusterindex erstellen / neu erstellen, beginnt der Server, Seiten zu bestellen. Dies ist ein sehr ressourcenintensiver Vorgang. Ihr Tisch ist groß. Ich würde Ihnen raten, Ihre Tabelle in mehrere kleinere Tabellen aufzuteilen (dh eine Datennormalisierung durchzuführen), wenn dies möglich ist. Sie können auch eine leere Kopie dieser Tabelle erstellen, einen Clusterindex für eine leere Tabelle hinzufügen, alle Daten aus Ihrer Haupttabelle importieren und anschließend die Haupttabelle löschen.
Ich meine so etwas -
quelle
Um die Geschwindigkeit eines SQL-Befehls zu erhöhen, sollten Sie über eine ordnungsgemäß eingerichtete Datenbank verfügen. Daher hoffe ich, dass Ihre Datenbank auf einer anderen Festplatte gespeichert ist und sich Master und Tempdb auf einer eigenen Festplatte befinden.
Davon abgesehen gibt es mehrere Faktoren, die die Indexerstellung beeinflussen: Wenn die Tabelle bereits sortiert ist und es so aussieht, als würden Sie diese auf einer HEAP-Tabelle aufbauen, würde ich sagen, dass sie nicht sortiert ist, und die andere Komponente ist der Spaltentyp, nach dem Sie arbeiten erstellen den Index auf. Die in einem Clustered-Index enthaltenen Informationen sind durch die Anzahl der Spalten oder die Bytegröße der Spalten (je nachdem, was zuerst eintritt) begrenzt. Daher sind einige Spalten keine so guten Kandidaten für Clustered-Indizes.
Da Sie einen eindeutigen Index für eine Heap-Tabelle erstellen, sollten Sie diese bereinigen, damit Sie keine doppelten Werte haben. Dadurch müssen Sie den Index nicht erneut erstellen.
Bevor Sie die Indexerstellungsabfrage ausführen, führen Sie diese zuerst aus
Nachdem Sie dies ausgeführt und die doppelten Datensätze verarbeitet haben, können Sie Folgendes ausführen. Beachten Sie, dass hierfür zusätzlicher Speicherplatz benötigt wird, sodass Sie mindestens so viel Speicherplatz benötigen wie die Größe dieser Tabelle.
Dadurch wird die Sortierung (die beim Erstellen eines Index erforderlich ist) in der Tempdb-Datenbank erzwungen und anschließend zurück übertragen und Ihre Daten ersetzt.
Eine Alternative wäre, eine doppelte Tabelle mit demselben Namen, denselben Spalten usw. zu erstellen, den Clusterschlüssel hinzuzufügen, bevor Sie Datensätze hinzufügen und dann diesen Befehl ausführen:
Da es sich um eine Set-Operation handelt, sollte dies theoretisch viel schneller funktionieren, da der SQL Server mit Sets schneller arbeitet als mit Zeilen. Wenn Sie fertig sind, löschen Sie die erste Tabelle und benennen Sie die zweite Tabelle um.
Sollten Sie weitere Hilfe mit dem Befehl MERGE benötigen, finden Sie hier den Link zu MSDN: http://msdn.microsoft.com/en-us/library/bb510625.aspx
quelle