Ich muss 100 Millionen Datensätze in einer einzelnen Tabelle aktualisieren, um die Tabelle zu normalisieren, indem der varchar-Wert einer Spalte einfach durch eine ID ersetzt wird. (Ich sage "Ersetzen", aber ich schreibe die ID wirklich in eine andere Spalte.)
Ich versuche, den Datensatz zu normalisieren. Die noch nicht normalisierten Daten haben keine Indizierung. Mein Gedanke war, dass ich keine Indizes für die Rohwerte erstellen und warten würde, sondern stattdessen die Fremdschlüssel indizieren würde, die die varchar-Werte nach Abschluss der Aktualisierung durch tinyint-Werte ersetzen.
UPDATE A
SET A.AutoClassID = B.AutoClassID
FROM AutoDataImportStaging.dbo.Automobile as A
JOIN AutoData.dbo.AutoClass as B on (A.AutoClassName = B.AutoClassName)
Hintergrund
- Verwenden von MSSQL 2008 R2 auf Server 2008 R2
- Server hat 8 GB RAM
- Server hat ein RAID10, 7200 U / min SATA (nicht großartig, ich weiß, in der Produktion werden nur Daten gelesen und keine Daten geschrieben; plus der jüngste HD-Mangel machte dies aus Kostengründen notwendig)
- Der Server verfügt über eine Dual-Quad-Core-Xeon-CPU
- Die Maschine macht nichts anderes (derzeit nur für Entwickler, nur für diesen Prozess).
- einfache Protokollierung aktiviert (? - aber wird immer noch protokolliert, damit ein Rollback durchgeführt werden kann?)
- Beachten Sie, dass die Abfrage auf zwei verschiedene DBs verweist, was das wert ist
- "Breite" eines Datensatzes in der Tabelle, der aktualisiert wird, beträgt 455 Bytes
Ressourcen während der Ausführung
- Der physische Arbeitsspeicher ist voll
- Die Festplatten-E / A ist maximal
- CPU macht kaum etwas (Choke-Punkt ist I / O)
- Die Laufzeit betrug 14 Stunden und es wird gezählt!
Ich vermute ein paar Dinge, wie ich einen Index für die Rohdaten benötige, obwohl ich die Spalte (AutoClassName) nach den Normalisierungsaktualisierungen löschen werde. Ich frage mich auch, ob ich anstelle des JOIN nur einen Datensatz nach dem anderen durchgehen sollte, was zu dem Zeitpunkt, als ich damit anfing, lächerlich schien, aber jetzt scheint es, dass das schneller gewesen wäre.
Wie kann ich meine Methodik für meine verbleibenden Normalisierungsaktualisierungen (ähnlich wie diese) schneller ändern?
quelle
TOP
Klausel einverstanden . Das wäre mein Ansatz.Ich würde einen anderen Ansatz wählen.
Anstatt vorhandene Tabellen zu aktualisieren, erstellen Sie einfach eine neue Tabelle, die das enthält, was Sie benötigen.
Dies wird mit ziemlicher Sicherheit schneller sein:
Wie derzeit geschrieben, passieren viele logische Operationen:
quelle
Es wird nicht schneller sein, den Tisch eine Reihe nach der anderen zu durchlaufen!
Wie vermutet und von Ihnen bestätigt, ist dies E / A-gebunden - mit einer Festplatte konkurrieren Lese-, Schreib-, Transaktionsprotokolle und (beliebiger) temporärer Arbeitsbereich alle um dieselbe E / A.
Durch einfache Wiederherstellung werden die Transaktionen weiterhin protokolliert, das Protokoll wird jedoch von einem Prüfpunkt gelöscht. Es ist möglich, dass Ihre anfängliche Protokollgröße und die Einstellungen für das automatische Wachstum zu einer gewissen Verlangsamung der E / A führen. Das Transaktionsprotokoll muss vergrößert werden, um die Änderungen zu berücksichtigen.
Haben Sie versucht, das Feld AutoClassName zu indizieren? Wie viele verschiedene AutoClass-Werte gibt es?
Möglicherweise müssen Sie die Aktualisierungen stapelweise ausführen, basierend auf den Einschränkungen Ihrer E / A. Also 1 Million aktualisieren, Checkpoint, wiederholen ....
quelle
Erstellen Sie Indizes für die Verknüpfungsfelder.
Sie können die Indizes jederzeit löschen, wenn Sie fertig sind.
Ich wäre sehr überrascht, wenn die Indizes die Update-Leistung nicht wesentlich verbessern würden.
quelle
Exportieren Sie nach Ihren Wünschen, erstellen Sie eine neue Tabelle und importieren Sie sie zurück. Als Bonus hätten Sie eine Kopie der Daten als Backup, falls Wunder geschehen sollten.
quelle