SQL Server: esporta tabella di grandi dimensioni senza chiave primaria


9

Devo sincronizzare una tabella di grandi dimensioni ~ 500 milioni di righe senza una chiave primaria tra SQL Server e MySQL. La tabella ha solo un indice composito non univoco cluster.

Ho una connessione ODBC tra i server, ma un'importazione di ~ 8 milioni di righe ha richiesto circa 45 minuti, quindi credo che un'importazione singola più grande sarebbe irragionevole poiché potrebbero verificarsi interruzioni in qualsiasi momento. Non riesco a modificare la struttura della tabella esistente, posso aggiungere altre tabelle. Dopo ulteriori letture, offset / fetch non è un'opzione per le tabelle di grandi dimensioni. "Seleziona ... dove x tra ... e ..." non è un'opzione in quanto non ho una chiave univoca.

Come posso esportare la tabella in batch che sono garantiti per contenere tutte le righe? Il mio problema è che, poiché la chiave cluster non è univoca, ordinare dopo non garantirebbe che le righe fisiche abbiano lo stesso ordine tra query consecutive e l'ordine dopo che tutte le colonne richiederebbero troppo tempo. E come consiglieresti di migrare i batch, tramite file ODBC o CSV?


Sarà una ripetizione (operazione usuale) o una volta sola?
Bogdan Bogdanov,

L'esportazione iniziale sarà un'operazione una tantum, le modifiche di sincronizzazione come i nuovi record o gli aggiornamenti dovrebbero essere ripetitive. CDC non è un'opzione, ma esaminerà ulteriormente dopo la migrazione iniziale.
nessuno

Penso che per ricevere aiuto su questo devi spiegare più in dettaglio l'intero processo (sembra che tu abbia un problema molto complesso)
Bogdan Bogdanov

Si nota "poiché la chiave cluster non è univoca, ordinare dopo non garantirebbe che le righe fisiche abbiano lo stesso ordine tra query consecutive". Poiché l'ordine delle righe non viene conservato (a meno che non si disponga di alcuni dati di sequenza), non è possibile fare affidamento su come ottenere lo stesso ordine di righe fisico. L'ordine delle righe non è predefinito né nell'ordine di inserimento né nell'indice, ma è definito dalla clausola ORDER BY .
RLF,

Sì, RLF, sono d'accordo. Le colonne sono tutte ints, A, B, C, D, E. La chiave cluster è su ABC. Una combinazione ABC non è unica, né una combinazione ABCD. "Ordina per" una o più colonne non univoche mi consentirebbe di esportare l'intera tabella in lotti? E Bogdan Bodganov, la piattaforma Stack scoraggia problemi complessi, è meglio solo affrontare la domanda. Come esportare l'intera tabella di grandi dimensioni il più velocemente possibile in batch senza perdita di righe?
nessuno

Risposte:


0

Supponendo che non si disponga di aggiornamenti o eliminazioni rispetto alla tabella di origine, è possibile provare quanto segue:
1. Creare una copia della tabella esistente utilizzando la sintassi CTAS (per SQL Server è SELECT * into source_table_copy FROM source_table). Tale operazione è molto veloce anche per tavoli enormi.
2. Aggiungi after inserttrigger su source_tableche copia i nuovi record in source_table_copy.
3. Ora quando anche tutti i nuovi record source_tableentrano in source_table_copy, e puoi spostare i dati dalla tabella copiata a Mysql in batch. Ad esempio, se si dispone di un collegamento tra 2 server, tutto può essere eseguito all'interno della procedura memorizzata TSQL.
Ad esempio, potrebbe apparire un pezzo di codice che sposta fino a 20 record su un nuovo server

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

È anche possibile utilizzare CURSOR per leggere i dati e quindi eliminarli con la where current ofclausola.

** Idealmente è necessario impedire alle applicazioni di inserire dati nel source_tablepassaggio 1. Se è assolutamente impossibile, andrò con un after inserttrigger che viene aggiunto proprio prima del passaggio 1 e rimosso subito dopo aver fatto che copia i dati in un'altra tabella che posso successivamente si fondono con source_table_copy.


Grazie per la soluzione, stavo provando anche qualcosa, tuttavia con un normale inserto. Proverò la sintassi CTAS per vedere se accelera le cose. Domanda di follow-up, se non ti dispiace: il "trigger after insert" influenzerebbe le prestazioni?
nessuno il

Poiché il corpo del trigger è molto semplice (basta inserire i dati in un'altra tabella), l'impatto sulle prestazioni sarà minimo.
a1ex07,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.