2010-04-14 16 views
10

Was ist die effizienteste Methode zum Laden großer Datenmengen aus CSV (3 Millionen + Zeilen) in eine Datenbank?C# Importieren großer Datenmengen von CSV in Datenbank

  • Die Daten müssen formatiert werden (zB Name Spalte muss in Vornamen und Nachnamen aufgeteilt werden, etc.)
  • Ich brauche dies wie möglich, dh Zeitdruck in einem effizient zu tun

Ich habe die Möglichkeit, die Daten mit einer C# -Anwendung Zeile für Zeile zu lesen, zu transformieren und zu laden. Ist das ideal, wenn nicht, was sind meine Möglichkeiten? Sollte ich Multithreading verwenden?

+0

Wie streng sind die zeitlichen Einschränkungen? – Jake

Antwort

4

Sie werden I/O-gebunden sein, Multithreading wird es nicht unbedingt schneller laufen lassen.

Das letzte Mal, als ich dies tat, war es etwa ein Dutzend Zeilen C#. In einem Thread lief die Festplatte so schnell, wie sie Daten von den Platten lesen konnte. Ich lese Zeile für Zeile aus der Quelldatei.

Wenn Sie nicht daran interessiert sind, es selbst zu schreiben, könnten Sie die FileHelpers Bibliotheken versuchen. Sie können auch einen Blick auf Sébastien Lorion's work werfen. Sein CSV-Reader wurde speziell für Leistungsprobleme geschrieben.

+0

Ja, die C# io-Bibliothek ist gut mit Puffer gemacht. Kürzlich musste ich in einer Minute von einem CSV zu einem anderen (1,5 m Zeilen) transformieren. –

+1

Ich empfehle auch FileHelpers. Es hat mich davor bewahrt, einen Parser schreiben zu müssen, um mit Werten umzugehen, die Kommas enthalten. Wenn die CSV solche unangenehmen Details enthält, sollten Sie FileHelpers in Erwägung ziehen. –

+0

Ich weiß, dass in der Vergangenheit die Suchzeit auf Laufwerken ein Problem war. Im Fall von großen Bilddateien würden wir von einem Laufwerk lesen und in ein anderes schreiben, um die Anzahl der Neupositionierungen der Laufwerksköpfe zu reduzieren. – yamspog

2

Ich würde Ihrer Lösung zustimmen. Das Lesen der Datei um jeweils eine Zeile sollte den Aufwand für das Lesen der gesamten Datei in den Speicher auf einmal vermeiden, wodurch die Anwendung schnell und effizient ausgeführt werden kann, wobei zunächst Zeit benötigt wird, um die Datei zu lesen (was relativ schnell ist) und die Zeilen zu analysieren . Die einzige Vorsichtsmaßnahme, die ich für Sie habe, ist, darauf zu achten, ob Sie neue Zeilenumbrüche in Ihre CSV-Datei eingefügt haben. Ich weiß nicht, ob das spezifische CSV-Format, das Sie verwenden, tatsächlich Zeilenumbrüche zwischen Anführungszeichen in den Daten ausgibt, aber das könnte diesen Algorithmus natürlich verwirren.

Ich würde auch vorschlagen, die INSERT-Anweisungen (einschließlich vieler INSERT-Anweisungen in einer Zeichenfolge) zu verarbeiten, bevor sie an die Datenbank gesendet werden, wenn dies keine Probleme beim Abrufen generierter Schlüsselwerte für nachfolgende Fremdschlüssel ergibt (hoffentlich müssen Sie keine generierten Schlüsselwerte abrufen). Denken Sie daran, dass SQL Server (wenn Sie das verwenden) nur 2200 Parameter pro Batch verarbeiten kann. Beschränken Sie daher Ihre Batchgröße, um dies zu berücksichtigen. Und ich würde empfehlen, parametrisierte TSQL-Anweisungen zu verwenden, um die Einsätze durchzuführen. Ich vermute, dass mehr Zeit damit verbracht wird, Datensätze einzufügen, als sie aus der Datei zu lesen.

1

Sie geben nicht an, welche Datenbank Sie verwenden, aber angesichts der Sprache, die Sie erwähnen, ist C# Ich gehe von SQL Server aus.

Wenn die Daten nicht mit BCP importiert werden können (was nicht so klingt, als ob sie verarbeitet werden müssen), dann ist SSIS wahrscheinlich die nächst schnellere Option. Es ist nicht die schönste Entwicklungsplattform der Welt, aber es ist extrem schnell. Sicherlich schneller als jede Anwendung, die Sie in einem vernünftigen Zeitrahmen selbst schreiben könnten.

+0

Ich bin mit Greg und JayRiggs auf diesem. Überspringen Sie das C# (außer Sie schreiben ein CLR-Modul für SQL Server). Lass SQL die Arbeit machen. Es ist ziemlich gut mit Massenvolumen von Daten aus Dateien zu arbeiten, falls Sie nicht gehört haben. ;) Damit ersparen Sie sich beim Öffnen von Contxns etc. alle möglichen Kopfschmerzen. – jcolebrand

+0

Das macht es sehr schwierig für Unit-Tests? – guazz

+0

Dies ist nicht wirklich die Art von Problem, wo Unit-Tests viel nutzen. Die Leute konzentrieren sich zu sehr auf Unit Testing und ignorieren das größere Bild. Was Sie testen sollten, ist, dass die Daten, die in die Datenbank gelangen, korrekt sind, wenn Sie einen bekannten Datensatz in einer CSV-Datei verwenden und bekannte Fälle wie erwartet behandelt werden (entweder behoben, verworfen oder fehlgeschlagen). Wenn Sie es so machen, spielt es keine Rolle, wie es in die Datenbank kommt. Aus jeder praktischen Perspektive würde ich sagen, SSIS ist genauso überprüfbar wie alles andere. –

3

Sie könnten die csvreader verwenden, um die CSV schnell zu lesen. Wenn Sie SQL Server verwenden, verwenden Sie CachedCsvReader von csvreader, um die Daten in eine DataTable zu lesen, die Sie mit SqlBulkCopy zum Laden in SQL Server verwenden können

+0

Das ist was ich benutze. Ich mag csvreader, es ist eine sehr bequeme Möglichkeit, auf eine Datei mit Trennzeichen zuzugreifen. – galford13x

+0

+1 für die SqlBulkCopy – Kiril

0

BCP ist ziemlich schnell, also würde ich das zum Laden der Daten verwenden. Für die String-Manipulation würde ich mit einer CLR-Funktion auf SQL gehen, sobald die Daten da sind. Multi-Threading wird in diesem Szenario nicht helfen, außer Komplexität hinzuzufügen und die Leistung zu beeinträchtigen.

0

Wenn Sie es wirklich in C# erstellen möchten, erstellen Sie & füllen Sie eine DataTable, schneiden Sie die Ziel-DB-Tabelle und verwenden Sie dann System.Data.SqlClient.SqlBulkCopy.WriteToServer (DataTable dt).

+0

Leider muss ich vorhandene Datensätze aktualisieren und die Daten werden täglich geladen. – guazz

Verwandte Themen