Effiziente Übertragung großer Datenmengen (84 Millionen Zeilen)

11

Ich habe ungefähr 84 Millionen Zeilen. Von diesen müssen alle in eine separate Datenbank auf demselben Server übertragen werden. Dann lösche ich, um ungefähr 60 Millionen Zeilen aus der Quellendatenbank zu löschen.

Die 84 Millionen Zeilen befinden sich alle in derselben Tabelle. Allein diese Tabelle macht 90% der gesamten Datenbank aus.

Also ... Quelle: 84 Millionen Zeilen -> 24 Millionen Zeilen Ziel: 0 Zeilen -> 84 Millionen Zeilen

Die Quelle wird im vollständigen Wiederherstellungsmodus ausgeführt, das Ziel wird einfach ausgeführt.

Ich frage mich, was der effizienteste Weg wäre, dies zu tun.

Plan A:

1) INSERT INTO Ziel SELECT * FROM Quelle

2) TRUNCATE-Quelle

3) INSERT INTO source SELECT * FROM Ziel WHERE keep_condition = 1

Plan B:

1) Stellen Sie eine Sicherung der Quellendatenbank als Zieldatenbank wieder her

2) Löschen Sie alle Tabellen mit Ausnahme der in der Zieldatenbank benötigten

3) TRUNCATE-Quelle

4) INSERT INTO source SELECT * FROM Ziel WHERE keep_condition = 1

Plan C:

1) INSERT INTO Ziel SELECT * FROM Quelle

2) DELETE source WHERE keep_condition = 0

oder etwas anderes?

Vielen Dank

elty123
quelle
Warum verwenden Sie nicht den Assistenten zum Importieren und Exportieren von Daten? Es ist ein Tool, das mit der Installation von SQL Server bereitgestellt wird.
Hani El Mouallem
Ist es möglich, die 24-mil-Zeilen in eine neue Tabelle zu kopieren und die beiden Zeilen dann einfach nach Bedarf umzubenennen, damit Sie 84 Millionen Zeilen nicht unnötig verschieben?
LowlyDBA
Ist das ein einmaliger oder laufender Prozess? Ich frage, weil es angesichts der Zeit, die für die Verarbeitung von 80 Millionen Zeilen benötigt wird, wahrscheinlich Datenänderungen in SOURCE gibt, die Zeilen erzeugen, die jetzt in DESTINATION leben sollten.
Michael Green
Dies sieht nach einem XY-Problem aus: Sie müssen alle 84-MM-Zeilen in einer Datenbank und 24-MM-Zeilen in einer zweiten Datenbank haben. Welche Geschäftsanforderungen erfordern, dass 84 Millionen verschoben und 60 Millionen gelöscht werden, anstatt nur 24 Millionen zu verschieben? Link: meta.stackexchange.com/questions/66377/what-is-the-xy-problem )
Pieter Geerkens
Ich habe ein sehr ähnliches Problem und es ist eindeutig nicht XY. Vor der Verbreitung der Gesetze zur Aufbewahrung von Aufzeichnungen haben wir alle Daten aufbewahrt. Jetzt müssen wir Zeilen löschen, die älter sind als das Datum, an dem wir gesetzlich verpflichtet sind, sie zu behalten. Dies bedeutet, dass Daten im Wert von über 20 Jahren archiviert und gelöscht werden, da die rechtliche Aufbewahrung in den meisten Fällen 7 Jahre beträgt. Ich glaube nicht, dass ich allein bin, wenn ich glaube, dass Microsoft nicht in der Lage ist, gespeicherte Prozeduren mit der Funktion "Massenkopie" zu versehen. Eine App sollte beim Verschieben von Daten innerhalb einer Datenbank nicht schneller sein als die Datenbank selbst. Nächstes Jahr muss ein weiteres Jahr archiviert werden.
Bielawski

Antworten:

11

Ich würde hinzufügen, dass Sie diese Transaktionen stapeln müssen , auch wenn Sie sich dazu entschließen . Ich hatte in letzter Zeit sehr viel Glück mit dem verlinkten Artikel und ich schätze die Art und Weise, wie Indizes im Gegensatz zu den meisten Batch-Lösungen, die ich sehe, genutzt werden.

Selbst wenn sie nur minimal protokolliert werden, handelt es sich um große Transaktionen , und Sie könnten viel Zeit damit verbringen, sich mit den Folgen eines abnormalen Protokollwachstums (VLFs, Abschneiden, richtige Größe usw.) zu befassen.

Vielen Dank

Erik Darling
quelle
3

"Effizient" kann für die Verwendung von Protokolldateien, die E / A-Leistung, die CPU-Zeit oder die Ausführungszeit gelten.

Ich würde versuchen, einen minimal protokollierten Vorgang zu erreichen, der aus Sicht der Protokollierung ziemlich effizient wäre. Dies sollte Ihnen einige Ausführungszeiten und einen Bonus ersparen. Wenn Sie über den temporären Speicherplatz verfügen, funktioniert möglicherweise Folgendes für Sie.

CREATE TABLE #temp;
ALTER source -> BULK_LOGGED recovery model

BEGIN TRANSACTION;

    INSERT INTO dest SELECT FROM source;
    INSERT INTO #temp SELECT FROM source WHERE keep_condition=1;
    TRUNCATE TABLE source;
    INSERT INTO source SELECT FROM #temp;

COMMIT TRANSACTION;

ALTER source -> FULL recovery model
DROP TABLE #temp;

Damit ein minimal protokollierter Vorgang ausgeführt werden kann, müssen eine Reihe von Bedingungen erfüllt sein, einschließlich der derzeit ausgeführten Sicherungen, der Datenbank, die auf den BULK_LOGGEDWiederherstellungsmodus eingestellt ist, und abhängig von Ihren Indizes muss die Zieltabelle möglicherweise leer sein. Einige dieser Verhaltensweisen haben sich auch von SQL Server 2005 auf 2008 geändert (verbessert).

Andererseits können alle anderen Optionen, ohne die Besonderheiten Ihrer Tabelle und Ihrer Daten zu kennen, eine bessere Leistung erbringen. Versuchen Sie es mit

SET STATISTICS IO ON;
SET STATISTICS TIME ON;

.. und sehen, welche am besten funktioniert.

BEARBEITEN : Wenn Sie massenprotokollierte Vorgänge ausführen, stellen Sie sicher, dass Sie vor und nach dem Vorgang eine Sicherung (Voll- oder Transaktionsprotokoll) erstellen, wenn Sie zu einem bestimmten Zeitpunkt eine Wiederherstellungsfunktion benötigen und den Verdacht haben, dass andere Aktivitäten in der Datenbank unter ausgeführt werden zur gleichen Zeit, zu der Ihr ETL-Job ausgeführt wird.

Ich habe vor einiger Zeit einen Blog-Beitrag über minimal protokollierte Vorgänge geschrieben. Dort finden Sie Links zu anderen Beiträgen und Dokumentationen.

Daniel Hutmacher
quelle
+1 für die Empfehlung von OP, zu testen, welche Leistung besser ist. Natürlich könnte es ein bisschen schwierig sein, reelle Zahlen zu erhalten, es sei denn, er hat ein doppeltes System in dev usw.
Max Vernon
Nur eine Frage: Was würde passieren, wenn Sie versuchen, eine Wiederherstellung zu einem bestimmten Zeitpunkt durchzuführen, wenn sich die Datenbank im Massenprotokollierungsmodus befindet? Ich nahm an, dass jede Transaktion, die nicht als "Bulk" qualifiziert ist, wiederhergestellt werden kann.
elty123
1
@ elty123 Bei der Massenprotokollwiederherstellung können Sie nur bis zum Ende Ihrer letzten Protokollsicherung wiederherstellen. Es gibt keinen Zeitpunkt für eine Wiederherstellung, wie dies bei einer vollständigen Wiederherstellung der Fall wäre. Normalerweise wechseln Sie zur Massenprotokollwiederherstellung, führen einen ETL-Prozess aus, wechseln wieder zur vollständigen Wiederherstellung und erstellen dann eine Protokollsicherung.
RubberChickenLeader
@WindRaven Das ist nicht richtig - siehe meine Antwort unten.
wBob
1
@wBob und @WindRaven, ich habe meine Antwort aktualisiert, um die Notwendigkeit widerzuspiegeln, vor und nach der Verwendung des BULK_LOGGEDModus Backups zu erstellen . Vielen Dank!
Daniel Hutmacher
1

Warum nicht BCP?

  1. Sichern Sie die Quelle
  2. Ändern Sie sourcecedb in Bulk-Loged
  3. Öffnen Sie die Eingabeaufforderung

  4. bcp server.sourcedb.table out Filename.flt -T -c

  5. bcp "SELECT * FROM sourcedb.table WHERE keep_condition = 1" queryout Filename2.flt -T -c

  6. bcp Server.destinationdb.table in Filename.flt -T -c -b1000

  7. Überprüfen Sie die Daten

  8. Von SSMS Schneiden Sie die Sourcing-Tabelle ab
  9. bcp server.sourcedb.table in Filename2.flt -T -c -b1000
  10. Ändern Sie die Quelle wieder auf voll
Stacylaray
quelle
2
Weil sie sich auf demselben Server befinden. Das Schreiben in das Dateisystem wäre teuer. Es ist besser, eine Datenbank zu erstellen und deren Größe zu ändern, um hoffentlich die sofortige Initialisierung der Dateien zu nutzen. Dies wäre eine vernünftige Wahl für dbs auf verschiedenen Servern, obwohl SSIS meine erste Wahl wäre, wenn verfügbar. Hinweis: Option -n (nativ) ist kompakter und sicherer zum Verschieben von Daten von SQL Server nach SQL Server. Option -b hat keine Auswirkung auf bcp out.
wBob
0

Denken Sie nicht, dass Sie empfehlen sollten, das Wiederherstellungsmodell vorher und nachher ohne vollständige Datenbanksicherung oder T-Log-Sicherung zu ändern . Eine der Funktionen des BULK_LOGGED-Wiederherstellungsmodells besteht darin, dass Sie nicht mehr in der Lage sind, zu einem bestimmten Zeitpunkt eine Wiederherstellung für T-Protokolle durchzuführen, die massenprotokollierte Vorgänge enthalten. Klassisches Szenario: nächtliche vollständige Sicherung, stündliche T-Log-Sicherungen. Sie ändern das Wiederherstellungsmodell in "Massenprotokolliert" und starten den Vorgang. Es läuft etwas schief und die Transaktion wird zurückgesetzt (oder Sie haben noch keine verwendet). Sie sind sich jedoch nicht sicher, was sonst noch in der Datenbank vor sich ging, und möchten daher einen bekannten guten Punkt wiederherstellen.

Wann können Sie wiederherstellen? Letzte stündliche T-Log-Sicherung, die keine Massenprotokollierungsvorgänge enthält und möglicherweise n Minuten an Transaktionen verliert. Eine vollständige Sicherung oder T-Log-Sicherung vor dem Ändern des Wiederherstellungsmodells erstellt einen Fallback-Punkt. Welches Sie wählen, hängt von Ihrer RTO ab.

wBob
quelle
0

Das Löschen von Partitionen aus einer Tabelle ist eine sehr schnelle und ressourcenschonende Methode, um große Datenmengen aus einer Tabelle zu entfernen. Wäre diese Tabelle so partitioniert, dass Ihre Quell- / Zielaufteilung unterstützt wird, besteht die Antwort darin, eine Kopie wiederherzustellen, die redundanten Tabellen und redundanten Partitionen vom Ziel zu löschen und die komplementären Partitionen von der Quelle zu löschen.

Die Kosten für die Aktivierung der Partitionierung können dies jedoch insgesamt zu einem teureren Vorgang machen.

Michael Green
quelle