SQL Server - Große Tabelle ohne Primärschlüssel exportieren

9

Ich muss eine große Tabelle ~ 500 Millionen Zeilen ohne Primärschlüssel zwischen SQL Server und MySQL synchronisieren. Die Tabelle enthält nur einen zusammengesetzten nicht eindeutigen Clustered-Index.

Ich habe zwar eine ODBC-Verbindung zwischen den Servern, aber ein Import von ~ 8 Millionen Zeilen dauerte ungefähr 45 Minuten. Daher halte ich einen größeren Einzelimport für unangemessen, da zu jedem Zeitpunkt Unterbrechungen auftreten können. Ich kann die vorhandene Tabellenstruktur nicht ändern, ich kann andere Tabellen hinzufügen. Nach dem weiteren Lesen ist Offset / Fetch keine Option für große Tabellen. "Wählen Sie ... wobei x zwischen ... und ..." ist keine Option, da ich keinen eindeutigen Schlüssel habe.

Wie kann ich die Tabelle in Stapeln exportieren, die garantiert alle Zeilen enthalten? Mein Problem ist, dass, da der Clustered-Schlüssel nicht eindeutig ist, die Reihenfolge danach nicht garantiert, dass die physischen Zeilen zwischen aufeinanderfolgenden Abfragen dieselbe Reihenfolge haben, und die Reihenfolge, nachdem alle Spalten zu lange dauern würden. Und wie würden Sie empfehlen, die Stapel über ODBC- oder CSV-Dateien zu migrieren?

Niemand
quelle
Dies wird eine Wiederholung (übliche Operation) oder eine einmalige Operation sein?
Bogdan Bogdanov
Der anfängliche Export ist eine einmalige Operation. Die Synchronisierungsänderungen wie neue Datensätze oder Aktualisierungen sollten sich wiederholen. CDC ist keine Option, wird jedoch nach der ersten Migration weiter untersucht.
Niemand
Ich denke, um Hilfe zu erhalten, müssen Sie den gesamten Prozess genauer erklären (es sieht so aus, als hätten Sie ein sehr komplexes Problem)
Bogdan Bogdanov
Sie stellen fest, "da der Clusterschlüssel nicht eindeutig ist, würde eine Reihenfolge nach der Bestellung nicht garantieren, dass die physischen Zeilen zwischen aufeinanderfolgenden Abfragen dieselbe Reihenfolge haben". Da die Zeilenreihenfolge nicht beibehalten wird (es sei denn, Sie haben einige Sequenzdaten), können Sie sich nicht darauf verlassen, dass Sie dieselbe physische Zeilenreihenfolge erhalten. Die Reihenfolge der Zeilen ist standardmäßig weder die Einfügereihenfolge noch die Indexreihenfolge, sondern wird durch die ORDER BY- Klausel definiert.
RLF
Ja, RLF, ich stimme zu. Die Spalten sind alle Ints, A, B, C, D, E. Der Clustered Key befindet sich auf ABC. Eine Kombination ABC ist weder eindeutig noch eine Kombination ABCD. Würde "Bestellen nach" einer nicht eindeutigen Spalte (n) es mir ermöglichen, die gesamte Tabelle in Stapeln zu exportieren? Und Bogdan Bodganov, Stack-Plattform, entmutigt komplexe Probleme. Es ist besser, nur die Frage zu beantworten. Wie exportiere ich die komplette große Tabelle so schnell wie möglich in Stapeln ohne Zeilenverlust?
Niemand

Antworten:

0

Angenommen, Sie haben keine Aktualisierungen oder Löschungen
für die Quelltabelle, können Sie Folgendes versuchen: 1. Erstellen Sie eine Kopie der vorhandenen Tabelle mithilfe der CTAS-Syntax (für SQLServer ist dies der Fall SELECT * into source_table_copy FROM source_table). Ein solcher Vorgang ist selbst bei großen Tischen sehr schnell.
2. Fügen Sie einen after insertTrigger hinzu source_table, in den neue Datensätze kopiert werden source_table_copy.
3. Jetzt source_tablegehen auch alle neuen Datensätze zu source_table_copyund Sie können Daten stapelweise aus der kopierten Tabelle nach MySQL verschieben. Wenn Sie beispielsweise eine Verbindung zwischen zwei Servern haben, kann alles innerhalb der gespeicherten TSQL-Prozedur ausgeführt werden.
Beispielsweise könnte ein Code aussehen, der bis zu 20 Datensätze auf einen neuen Server verschiebt

 --declare table variable to keep deleted records until they delivered to target host 
  BEGIN TRANSACTION;
  DELETE TOP (20) FROM source_table_copy OUTPUT DELETED.* INTO @Table_Var;

  --insert data into linked server , or to csv file
  COMMIT; 

Es ist auch möglich, mit CURSOR Daten zu lesen und dann mit where current ofKlausel zu löschen .

** Idealerweise müssen Sie verhindern, dass Anwendungen in source_tableSchritt 1 Daten einfügen . Wenn dies absolut unmöglich ist, verwende ich einen after insertTrigger, der unmittelbar vor Schritt 1 hinzugefügt und direkt nach Abschluss entfernt wird, um Daten in eine andere Tabelle zu kopieren, die ich kann später zusammenführen mit source_table_copy.

a1ex07
quelle
Vielen Dank für die Lösung, ich habe auch etwas ausprobiert, allerdings mit einem normalen Einsatz. Ich werde die CTAS-Syntax ausprobieren, um zu sehen, ob sie die Dinge beschleunigt. Folgefrage, wenn Sie nichts dagegen haben: Würde der "After Insert Trigger" die Leistung beeinträchtigen?
Niemand
Da der Triggerkörper sehr einfach ist (fügen Sie einfach Daten in eine andere Tabelle ein), sind die Auswirkungen auf die Leistung minimal.
a1ex07