SQL Server - Eksportuj dużą tabelę bez klucza podstawowego

9

Muszę zsynchronizować dużą tabelę ~ 500 milionów wierszy bez klucza podstawowego między SQL Server i MySQL. Tabela ma tylko klastrowy, niejednorodny indeks złożony.

Mam połączenie ODBC między serwerami, ale import ~ 8 milionów wierszy zajął około 45 minut, więc uważam, że większy pojedynczy import byłby nieuzasadniony, ponieważ mogą wystąpić przerwy w dowolnym momencie. Nie mogę zmienić istniejącej struktury tabel, mogę dodać inne tabele. Po dalszym czytaniu przesunięcie / pobranie nie jest opcją dla dużych tabel. „Wybierz… gdzie x między… a…” nie jest opcją, ponieważ nie mam unikalnego klucza.

Jak mogę wyeksportować tabelę partiami, które z pewnością zawierają wszystkie wiersze? Mój problem polega na tym, że ponieważ klucz klastrowany nie jest unikalny, kolejność po nim nie gwarantuje, że wiersze fizyczne mają taką samą kolejność między kolejnymi zapytaniami, a kolejność po wszystkich kolumnach potrwa zbyt długo. A w jaki sposób zaleciłbyś migrację partii za pomocą plików ODBC lub CSV?

nikt
źródło
To będzie powtarzanie (operacja ususal) lub operacja jednorazowa?
Bogdan Bogdanov
Początkowy eksport będzie operacją jednorazową, zmiany synchronizacji, takie jak nowe rekordy lub aktualizacje, powinny się powtarzać. CDC nie jest opcją, ale będzie badać dalej po początkowej migracji.
nikt
Myślę, że aby uzyskać pomoc, musisz bardziej szczegółowo wyjaśnić cały proces (wygląda na to, że masz bardzo złożony problem)
Bogdan Bogdanov
Uwaga: „ponieważ klucz klastrowany nie jest unikalny, kolejność po nim nie gwarantuje, że wiersze fizyczne mają taką samą kolejność między kolejnymi zapytaniami”. Ponieważ kolejność wierszy nie jest zachowana (chyba że masz jakieś dane sekwencji), nie możesz polegać na uzyskaniu tej samej fizycznej kolejności wierszy. Kolejność wierszy nie jest domyślnie zgodna z kolejnością wstawiania ani kolejnością indeksowania, ale jest zdefiniowana w klauzuli ORDER BY .
RLF
Tak, RLF, zgadzam się. Wszystkie kolumny to ints, A, B, C, D, E. Klawisz klastrowy znajduje się na ABC. Kombinacja ABC nie jest unikalna, ani kombinacja ABCD. Czy „sortowanie według” nieunikalnych kolumn (y) pozwoliłoby mi eksportować całą tabelę partiami? I Bogdan Bodganov, platforma Stack odradza złożone problemy, lepiej po prostu odpowiedzieć na pytanie. Jak eksportować kompletny duży stół tak szybko, jak to możliwe partiami, bez utraty wierszy?
nikt

Odpowiedzi:

0

Zakładając, że nie masz aktualizacji lub usunięć względem tabeli źródłowej, możesz spróbować wykonać następujące czynności:
1. Wykonaj kopię istniejącej tabeli przy użyciu składni CTAS (dla SQLServer to SELECT * into source_table_copy FROM source_table). Taka operacja jest bardzo szybka nawet dla dużych tabel.
2. Dodaj after insertwyzwalacz dla source_tabletej kopii nowych rekordów do source_table_copy.
3. Teraz, kiedy wszystkie nowe rekordy w source_tablepodróży do source_table_copyjak dobrze, i można przenieść dane z tabeli skopiowany do MySQL w partii. Na przykład, jeśli masz łącze między 2 serwerami, wszystko można zrobić w ramach procedury przechowywanej TSQL.
Np. Może wyglądać fragment kodu przenoszący do 20 rekordów na nowy serwer

 --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; 

Możliwe jest również użycie kursora do odczytu danych, a następnie usunięcia z where current ofklauzulą.

** Idealnie, musisz uniemożliwić aplikacjom wstawianie danych w source_tablekroku 1. Jeśli to absolutnie niemożliwe, pójdę z after insertwyzwalaczem, który jest dodawany tuż przed krokiem 1 i usuwany zaraz po zakończeniu, który kopiuje dane do innej tabeli, którą mogę później połączyć z source_table_copy.

a1ex07
źródło
Dziękuję za rozwiązanie, próbowałem też czegoś, jednak z normalną wkładką. Wypróbuję składnię CTAS, aby zobaczyć, czy to przyspiesza. Dalsze pytanie, jeśli nie masz nic przeciwko: czy wyzwalacz „po wstawieniu” wpłynie na wydajność?
nikt
Ponieważ element wyzwalający jest bardzo prosty (wystarczy wstawić dane do innej tabeli), wpływ na wydajność będzie minimalny.
a1ex07