2010-04-14 7 views
10

Qual è il metodo più efficiente per caricare grandi volumi di dati da CSV (3 milioni + righe) in un database.C# Importazione di un grande volume di dati dal CSV al database

  • I dati deve essere formattato (ad esempio colonna del nome deve essere diviso in nome e cognome, ecc)
  • ho bisogno di fare questo in un modo più efficiente possibile ad esempio vincoli di tempo

Sono schierato con l'opzione di leggere, trasformare e caricare i dati utilizzando un'applicazione C# riga per fila? Questo è l'ideale, se no, quali sono le mie opzioni? Dovrei usare il multithreading?

+0

Quanto sono rigidi i limiti di tempo? – Jake

risposta

4

Sarai vincolato all'I/O, quindi il multithreading non lo renderà necessariamente più veloce.

L'ultima volta che l'ho fatto, era circa una dozzina di righe di C#. In un thread ha eseguito il disco rigido il più velocemente possibile in grado di leggere i dati dai piatti. Ho letto una riga alla volta dal file sorgente.

Se non si è interessati a scrivere da soli, è possibile provare le librerie FileHelpers. Si potrebbe anche voler dare un'occhiata a Sébastien Lorion's work. Il suo lettore CSV è scritto appositamente per affrontare i problemi di prestazioni.

+0

sì, la libreria C# io è ben fatta con il buffer. Recentemente ho dovuto trasformare da un CSV ad un altro (linee da 1,5 m) in qualcosa come un minuto. –

+1

Raccomando anche FileHelpers. Mi ha salvato dal dover scrivere un parser per gestire i valori che contengono virgole. Se il CSV ha dettagli così brutti, considera FileHelpers. –

+0

so che in passato il tempo di ricerca su unità era un problema. nel caso di file di immagine di grandi dimensioni, dovremmo leggere da un'unità e scrivere su un'altra per ridurre il numero di volte in cui riposizionare le testine dell'unità. – yamspog

2

Sono d'accordo con la vostra soluzione. Leggere il file una riga alla volta dovrebbe evitare l'overhead di leggere l'intero file in memoria in una volta, il che dovrebbe rendere l'applicazione eseguita in modo rapido ed efficiente, principalmente prendendo tempo per leggere dal file (che è relativamente veloce) e analizzare le righe . L'unica nota di cautela che ho per te è quella di stare attento se hai nuove linee incorporate nel tuo CSV. Non so se il formato CSV specifico che stai utilizzando potrebbe effettivamente generare righe nuove tra virgolette nei dati, ma questo potrebbe confondere questo algoritmo, ovviamente.

Inoltre, suggerirei il batching delle istruzioni di inserimento (includere molte istruzioni di inserimento in una stringa) prima di inviarle al database se questo non presenta problemi nel recupero dei valori chiave generati che è necessario utilizzare per le chiavi esterne successive (si spera che non sia necessario recuperare alcun valore chiave generato). Tenere presente che SQL Server (se è quello che si sta utilizzando) può gestire solo 2200 parametri per batch, quindi limitare le dimensioni del batch per tenerne conto. E vorrei raccomandare l'uso di istruzioni TSQL parametrizzate per eseguire gli inserti. Sospetto che verrà impiegato più tempo per inserire record anziché leggerli dal file.

1

Non si indica quale database si sta utilizzando, ma data la lingua che si cita è C# assumerò SQL Server.

Se i dati non possono essere importati usando BCP (che suona come se non fosse possibile se ha bisogno di un'elaborazione significativa) allora SSIS sarà probabilmente la prossima opzione più veloce. Non è la piattaforma di sviluppo più bella del mondo, ma è estremamente veloce. Certamente più veloce di qualsiasi applicazione tu possa scrivere da te in qualsiasi ragionevole lasso di tempo.

+0

Sono con Greg e JayRiggs su questo. Salta il C# (a meno che tu non stia scrivendo un modulo CLR per SQL Server). Lascia che SQL faccia il lavoro. È abbastanza buono lavorare con volumi di dati di massa da file, nel caso in cui non avessi sentito. ;) Questo ti farà risparmiare tutti i tipi di mal di testa sui conxns di apertura, ecc. – jcolebrand

+0

Ciò rende molto difficile il test dell'unità? – guazz

+0

Questo non è proprio il tipo di problema in cui il test unitario è molto utile. Le persone si concentrano troppo sui test unitari e ignorano il quadro generale. Quello che dovresti cercare di testare è che i dati che entrano nel database siano corretti, dati un insieme noto di dati in un CSV, e che i casi di notoria cattiva siano gestiti (fissi, scartati o falliti) come previsto. Se lo fai in quel modo, non importa in realtà come entra nel database. Quindi, da qualsiasi punto di vista pratico, direi che SSIS è altrettanto verificabile di qualsiasi altra cosa. –

3

È possibile utilizzare csvreader per leggere rapidamente il CSV.

Supponendo che si stia utilizzando SQL Server, si utilizza il csvreader CachedCsvReader per leggere i dati in un DataTable che è possibile utilizzare con SqlBulkCopy da caricare in SQL Server.

+0

Questo è quello che uso. Mi piace csvreader, è un modo molto conveniente per accedere a un file delimitato. – galford13x

+0

+1 per SqlBulkCopy – Kiril

0

BCP è piuttosto veloce, quindi lo userei per caricare i dati. Per la manipolazione delle stringhe andrei con una funzione CLR su SQL una volta che i dati sono lì. La multi-threading non aiuta in questo scenario se non per aggiungere complessità e prestazioni dannose.

0

Se si desidera veramente farlo in C#, creare & compilare un DataTable, troncare la tabella db di destinazione, quindi utilizzare System.Data.SqlClient.SqlBulkCopy.WriteToServer (DataTable dt).

+0

Purtroppo, ho bisogno di aggiornare i record esistenti e i dati verranno caricati ogni giorno. – guazz