Auflistung von mehr als 10 Millionen Datensätzen von Oracle mit C #

8

Ich habe eine Datenbank, die mehr als 100 Millionen Datensätze enthält. Ich führe eine Abfrage aus, die mehr als 10 Millionen Datensätze enthält. Dieser Prozess benötigt zu viel Zeit, daher muss ich diese Zeit verkürzen. Ich möchte meine erhaltene Datensatzliste als CSV-Datei speichern. Wie kann ich es so schnell und optimal wie möglich machen? Ich freue mich auf Ihre Vorschläge. Danke.

    
sinanakyazici 30.11.2011, 09:02
quelle

4 Antworten

11

Ich gehe davon aus, dass Ihre Abfrage bereits auf die benötigten Zeilen / Spalten beschränkt ist, und nutzt die Indizierung sehr gut.

Bei diesem Maßstab ist die einzige kritische Sache, dass Sie nicht versuchen, alles auf einmal in den Speicher zu laden; Vergessen Sie also Dinge wie DataTable und die meisten Vollfett-ORMs (die normalerweise versuchen, Zeilen einem Identity-Manager und / oder Change-Manager zuzuordnen). Sie müssten entweder das rohe IDataReader (von DbCommand.ExecuteReader ) oder eine API verwenden, die einen nicht gepufferten Iterator auf top erstellt (es gibt mehrere; ich bin voreingenommen gegenüber dapper) ). Zum Schreiben von CSV ist der Rohdatenleser wahrscheinlich in Ordnung.

Darüber hinaus: Sie können es nicht viel schneller machen, da Sie bandbreitenbeschränkt sind. Sie können die CSV-Datei auf dem Datenbankserver nur so erstellen, dass es keinen Netzwerk-Overhead gibt.

    
Marc Gravell 30.11.2011, 09:09
quelle
5

Die Chancen sind ziemlich gering, Sie müssen dies in C # tun. Dies ist die Domäne des Massenladens / -exports von Daten (häufig in Data Warehousing-Szenarien verwendet).

Viele (kostenlose) Werkzeuge (ich stelle mir sogar Toad von Quest Software vor) werden das robuster und effizienter machen, als Sie es in jeder Plattform schreiben können.

Ich habe die Vermutung, dass Sie dies für einen Endnutzer eigentlich nicht brauchen (die einfache Beobachtung ist, dass die Abteilungssekretärin tatsächlich keine Kopien davon versenden muss; es ist zu groß, um darin nützlich zu sein Weg).

Ich schlage vor, das richtige Werkzeug für den Job zu verwenden. Und was auch immer du tust,

  • donot rollen Ihre eigenen Datentypkonvertierungen
  • Verwenden Sie eine CSV-Datei mit zitierten Literalen und denken Sie daran, die doppelten Anführungszeichen in diesen
  • zu entfernen
  • denke an regionale Optionen (IOW: Benutze immer InvariantCulture für Export / Import!)
sehe 30.11.2011 09:23
quelle
2
  

"Dieser Vorgang benötigt zu viel Zeit, daher muss ich diese Zeit verkürzen."

Dieser Prozess besteht aus drei Teilprozessen:

  1. Abrufen von & gt; 10m Datensätze
  2. Datensätze in Datei schreiben
  3. Übertragen von Datensätzen über das Netzwerk (ich gehe davon aus, dass Sie mit einem lokalen Client mit einer entfernten Datenbank arbeiten)

Einige oder alle dieser Probleme können einen Engpass darstellen. Also, wenn Sie die gesamte verstrichene Zeit reduzieren möchten, müssen Sie herausfinden, wo die Zeit verbracht wird. Sie müssen wahrscheinlich Ihren C # -Code instrumentieren, um die Messwerte zu erhalten.

Wenn sich herausstellt, dass die Abfrage das Problem ist, müssen Sie es tunen. Indizes werden hier nicht helfen, da Sie einen großen Teil der Tabelle abrufen (& gt; 10%), so dass die Leistung eines vollständigen Tabellenscan erhöht wird. Zum Beispiel den Speicher zu erhöhen, um Disk-Sortierungen zu vermeiden. Eine parallele Abfrage könnte nützlich sein (wenn Sie Enterprise Edition haben und genügend CPUs haben). Stellen Sie außerdem sicher, dass das Problem kein Hardwareproblem ist (Spindelkonflikt, fehlerhafte Verbindungen usw.).

Kann das Schreiben in eine Datei das Problem sein? Vielleicht ist Ihre Festplatte aus irgendeinem Grund langsam (z. B. Fragmentierung) oder Sie haben möglicherweise mit anderen Prozessen zu kämpfen, die in dasselbe Verzeichnis schreiben.

Die Übertragung großer Datenmengen über ein Netzwerk ist offensichtlich ein potenzieller Engpass. Sind Sie sicher, dass Sie nur relevante Daten an den Kunden senden?

Eine alternative Architektur: Verwenden Sie PL / SQL, um die Datensätze in eine Datei auf dem Datenserver zu schreiben. Verwenden Sie Bulk Collect, um verwaltbare Batch-Datensätze abzurufen, und übertragen Sie die Datei dann am Ende ggf. über FTP dorthin, wo Sie sie benötigen Komprimiere es zuerst.

    
APC 30.11.2011 13:21
quelle
1

Die eigentliche Frage ist, warum Sie so viele Zeilen aus der Datenbank lesen müssen (und einen so großen Anteil des zugrunde liegenden Datensatzes). Es gibt viele Ansätze, die dieses Szenario vermeidbar machen sollten. Offensichtlich sind dies synchrone Verarbeitung, Message Queuing und Vorkonsolidierung.

Wenn Sie das jetzt beiseite lassen ... Wenn Sie die Daten konsolidieren oder filtern, können Sie die Daten im gesamten Netzwerk übertragen, auch wenn es nur für localhost ist. es gibt immer noch einen großen Overhead). Nochmal, wenn Sie nur es rauslassen wollen Eine flache Datei , die dies in C # implementiert, macht dir keinen Gefallen.

    
symcbean 30.11.2011 09:24
quelle

Tags und Links