Trasferimento efficiente di grandi quantità (84 milioni di righe) di dati


11

Ho circa 84 milioni di file. Di tutti questi devono essere trasferiti in un database separato sullo stesso server, quindi elimino per eliminare circa 60 milioni di righe dal database di origine.

Gli 84 milioni di righe sono tutti nella stessa tabella. Solo questa tabella rappresenta il 90% dell'intero database.

Quindi ... Fonte: 84 milioni di righe -> 24 milioni di righe Destinazione: 0 righe -> 84 milioni di righe

L'origine sta eseguendo la modalità di recupero completo, la destinazione sarà semplice.

Mi chiedo quale sarebbe il modo più efficace per farlo?

Piano A:

1) INSERIRE IN destinazione SELEZIONA * DA fonte

2) Sorgente TRUNCATE

3) INSERIRE nella sorgente SELEZIONA * DA destinazione DOVE keep_condition = 1

Piano B:

1) Ripristina un backup del database di origine come database di destinazione

2) Eliminare tutte le tabelle tranne quella necessaria nel database di destinazione

3) Sorgente TRUNCATE

4) INSERIRE nella sorgente SELEZIONA * DA destinazione DOVE keep_condition = 1

Piano C:

1) INSERIRE IN destinazione SELEZIONA * DA fonte

2) ELIMINA sorgente DOVE keep_condition = 0

o qualcos'altro?

Grazie


perché non usi la procedura guidata Importa ed esporta dati? è uno strumento fornito con l'installazione di SQL Server.
Hani El Mouallem,

È possibile copiare le 24 mil righe in una nuova tabella, quindi semplicemente rinominarle in base alle necessità in modo da non spostare mai inutilmente 84 milioni di righe?
LowlyDBA,

È un processo unico o in corso? Chiedo perché, dato il tempo necessario per elaborare 80 milioni di righe, è probabile che ci saranno cambiamenti di dati nelle righe che producono SOURCE che ora dovrebbero vivere in DESTINAZIONE.
Michael Green,

Questo sembra un problema XY: devi finire con tutte le righe 84MM in un DB e 24MM di quelle in un secondo DB. Quali requisiti aziendali richiedono lo spostamento di 84 MM e l'eliminazione di 60 M, anziché lo spostamento di 24 MM? link: meta.stackexchange.com/questions/66377/what-is-the-xy-problem )
Pieter Geerkens,

Ho un problema molto simile e chiaramente non è XY. Prima della proliferazione delle leggi sulla conservazione dei dati abbiamo conservato tutti i dati. Ora dobbiamo eliminare le righe più vecchie della data in cui siamo tenuti legalmente a conservarle. Ciò significa archiviare ed eliminare i dati per oltre 20 anni poiché la conservazione legale nella maggior parte dei casi è di 7 anni. Non credo di essere il solo a credere che Microsoft non sia in grado di fornire la funzionalità di "copia bulk" alle stored procedure. Un'app non dovrebbe essere più veloce nello spostamento dei dati "all'interno" di un DB rispetto al DB stesso. L'anno prossimo deve essere archiviato un altro anno.
bielawski,

Risposte:


11

Aggiungo che, comunque tu decida di avvicinarti a questo, dovrai raggruppare queste transazioni . Di recente ho avuto molta fortuna con l'articolo collegato e apprezzo il modo in cui sfrutta gli indici rispetto alla maggior parte delle soluzioni in batch che vedo.

Anche minimamente registrate, queste sono grandi transazioni e potresti passare molto tempo a occuparsi delle ramificazioni di una crescita anomala dei tronchi (VLF, troncamento, dimensionamento corretto, ecc.).

Grazie


3

"Efficiente" potrebbe applicarsi all'utilizzo del file di registro, alle prestazioni I / O, al tempo della CPU o al tempo di esecuzione.

Proverei a realizzare un'operazione minimamente registrata, che sarebbe abbastanza efficiente dal punto di vista della registrazione. Questo dovrebbe farti risparmiare un po 'di tempo per l'esecuzione. Se si dispone dello spazio tempdb, potrebbe essere utile quanto segue.

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;

Affinché si verifichi un'operazione minimamente registrata, è necessario che siano presenti alcune condizioni, tra cui nessun backup attualmente in esecuzione, il database impostato sulla BULK_LOGGEDmodalità di ripristino e, a seconda degli indici, la tabella di destinazione potrebbe essere vuota. Alcuni di questi comportamenti sono anche cambiati (migliorati) da SQL Server 2005 a 2008.

Inoltre, senza conoscere i dettagli della tabella e dei dati, qualsiasi altra opzione potrebbe avere prestazioni migliori. Prova a usare

SET STATISTICS IO ON;
SET STATISTICS TIME ON;

.. e vedi quale funziona meglio.

MODIFICA : quando si eseguono operazioni registrate in blocco, assicurarsi di eseguire un backup (registro completo o delle transazioni) prima e dopo l'operazione se è necessaria la funzionalità di ripristino temporizzato e si sospetta che nel database potrebbero essere in corso altre attività su nello stesso momento in cui il lavoro ETL è in esecuzione.

Ho scritto un post sul blog sulle operazioni minimamente registrate qualche tempo fa, ci sono collegamenti lì ad altri post e documentazione.


+1 per aver consigliato all'OP di provare per vedere quale funziona meglio. Certo, potrebbe essere un po 'difficile ottenere numeri reali a meno che non abbia un sistema duplicato in sviluppo, ecc.
Max Vernon,

Solo una domanda, cosa accadrebbe se si provasse a eseguire un ripristino temporizzato quando il database era in modalità di registrazione in blocco? Supponevo che qualsiasi transazione che non fosse qualificata come "bulk" sarebbe recuperabile.
elty123,

1
@ elty123 Nel ripristino registrato in blocco è possibile ripristinare solo fino alla fine dell'ultimo backup del registro. Non vi è alcun punto nel tempo di recupero come sarebbe con il recupero completo. Normalmente si passa al ripristino di massa, si esegue un processo ETL, si torna al completo e si esegue un backup del registro.
RubberChickenLeader,

@WindRaven Questo non è corretto - vedi la mia risposta di seguito.
wBob,

1
@wBob e @WindRaven, ho aggiornato la mia risposta per riflettere la necessità di eseguire backup prima e dopo l'utilizzo della BULK_LOGGEDmodalità. Grazie!
Daniel Hutmacher,

1

Perché non BCP?

  1. Eseguire il backup del sourcedb
  2. Cambia sourcedb in log di massa
  3. Apri il prompt dei comandi

  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. controlla i dati

  8. Da SSMS Tronca la tabella sourcedb
  9. bcp server.sourcedb.table in Filename2.flt -T -c -b1000
  10. Cambia di nuovo a pieno

2
Perché sono sullo stesso server. Scrivere sul filesystem sarebbe costoso. Meglio creare un database e preimpostarlo, speriamo sfruttando l'inizializzazione istantanea dei file. Questa sarebbe una scelta ragionevole per dbs su server diversi sebbene SSIS sarebbe la mia prima scelta se disponibile. NB: L'opzione -n ​​(nativa) è più compatta e sicura per lo spostamento di dati da SQL Server a SQL Server. L'opzione -b non ha alcun effetto per bcp out.
wBob,

0

Non pensare che dovresti consigliare di cambiare il modello di recupero senza un backup completo del database o un backup t-log prima e dopo . Una delle funzionalità del modello di recupero BULK_LOGGED è la perdita della possibilità di eseguire il ripristino temporizzato per i log di t che contengono operazioni registrate in blocco. Scenario classico: backup completo notturno, backup t-log orari. Si modifica il modello di recupero in log di massa e si avvia l'operazione. Qualcosa va storto e la transazione torna indietro (o non l'hai usata). Tuttavia, non sei sicuro di cos'altro stia succedendo nel database, quindi vuoi ripristinare un buon punto noto.

Quando è possibile ripristinare in? Ultimo backup t-log orario che non contiene operazioni registrate in blocco, potenzialmente perdendo n minuti di transazioni. Un backup completo o backup t-log prima di modificare il modello di recupero creerà un punto di fallback. Quale scegli dipende dal tuo RTO.


0

Eliminare le partizioni da una tabella è un modo davvero rapido ed efficiente in termini di risorse per rimuovere grandi blocchi di dati da una tabella. Se questa tabella fosse partizionata in modo da supportare la divisione sorgente / destinazione, la risposta sarebbe ripristinare una copia, eliminare le tabelle ridondanti e le partizioni ridondanti dalla destinazione e eliminare le partizioni complementari dalla sorgente.

Il costo dell'abilitazione del partizionamento può tuttavia rendere l'operazione complessivamente più costosa.

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.