2013-12-16 10 views
11

Ich arbeite mit einer Oracle-Datenbank mit Millionen von Zeilen und über 100 Spalten. Ich versuche, diese Daten in einer HDF5-Datei unter Verwendung von Pytables mit bestimmten indizierten Spalten zu speichern. Ich werde Teilmengen dieser Daten in einem Pandas DataFrame lesen und Berechnungen durchführen.Lesen einer großen Tabelle mit Millionen von Zeilen von Oracle und Schreiben in HDF5

Ich habe versucht, die folgenden:

Laden Sie die in der Tabelle, ein Dienstprogramm in eine CSV-Datei, die CSV-Datei Chunk Chunk mit Pandas lesen und mit pandas.HDFStore zu HDF5 Tabelle anhängen. Ich habe eine dtype-Definition erstellt und die maximalen Zeichenfolgengrößen angegeben.

Aber jetzt, wenn ich versuche, Daten direkt von Oracle DB herunterzuladen und es in HDF5-Datei über pandas.HDFStore zu veröffentlichen, stoße ich auf einige Probleme.

pandas.io.sql.read_frame unterstützt kein Chunked-Lesen. Ich habe nicht genug RAM, um die gesamten Daten zuerst in den Speicher laden zu können.

Wenn ich versuche, cursor.fecthmany() mit einer festen Anzahl von Datensätzen zu verwenden, dauert die Leseoperation an der DB-Tabelle Alter wird nicht indiziert und ich muss Datensätze in einem Datumsbereich lesen. Ich benutze DataFrame(cursor.fetchmany(), columns = ['a','b','c'], dtype=my_dtype) aber der erstellte DataFrame leitet immer den dtype statt erzwingen den Dtype, die ich zur Verfügung gestellt habe (im Gegensatz zu read_csv, die an den dtype ich bereitstelle). Wenn ich diesen Datenrahmen an eine bereits existierende HDFDatastore angehängt habe, gibt es daher eine Typabweichung bei z. Ein float64 wird vielleicht als int64 in einem Chunk interpretiert.

Schätzen Sie, wenn Sie Ihre Gedanken anbieten könnten und zeigen Sie mir in die richtige Richtung.

+7

Ihr aktueller Ansatz (mit einem csv) und dtype Korrektur ist richtig. SQL wird ein großes Update in 0.14 bekommen (0.13 wird in Kürze veröffentlicht). Leider ist dtype ineference/chunking nicht verfügbar. Willkommen PRS ist aber! Siehe dieses Problem: https://github.com/pydata/pandas/issues/4163 – Jeff

+2

Ich schlage vor, das Oracle-Tag zu entfernen, es sei denn, Sie haben Probleme auf der Oracle-Seite der Dinge. –

+1

Sie sollten Ihre dba bitten, die Tabelle in ein bereichspartitioniertes Objekt umzuwandeln, danach sollte es einfach per Partition erreichbar sein. – klashxx

Antwort

0

okay, so dass ich nicht viel Erfahrung mit oracle-Datenbanken haben, aber hier ist ein paar Gedanken:

Ihre Zugriffszeit für bestimmte Datensätze von Oracle ist langsam, weil die Indexierung nicht ausreicht und die Daten in der Reihenfolge der Zeitstempel vorliegen müssen.

Erstens können Sie die Indizierung für die Datenbank nicht aktivieren?

Wenn Sie die Datenbank nicht bearbeiten können, können Sie vermutlich eine gefundene Menge anfordern, die nur die bestellten eindeutigen IDs für jede Zeile enthält?

Sie könnten diese Daten möglicherweise als ein einziges Array von eindeutigen IDs speichern, und Sie sollten in der Lage sein, in den Speicher zu passen. Wenn Sie 4k für jeden eindeutigen Schlüssel zulassen (konservative Schätzung, inkl. Overhead usw.) und Sie die Zeitstempel nicht behalten, so ist es nur ein Array von Ganzzahlen, es könnte etwa 1,1 GB RAM für 3 Millionen Datensätze verbrauchen. Das ist kein ganzer Haufen, und vermutlich wollen Sie nur ein kleines Fenster mit aktiven Daten, oder vielleicht bearbeiten Sie Zeile für Zeile?

Machen Sie eine Generatorfunktion, um all dies zu tun.Sobald Sie die Iteration abgeschlossen haben, sollte der Speicher freigegeben werden, ohne dass Sie etwas löschen müssen. Dadurch wird auch der Code leichter nachvollziehbar und die eigentliche wichtige Logik Ihrer Berechnungsschleife wird aufgebläht.

Wenn Sie nicht alles im Speicher speichern können, oder aus einem anderen Grund nicht funktioniert, dann ist das Beste, was Sie tun können, herauszufinden, wie viel Sie im Speicher speichern können. Sie können den Job möglicherweise in mehrere Anfragen aufteilen und Multithreading verwenden, um eine Anfrage zu senden, sobald die letzte fertig ist, während Sie die Daten in Ihrer neuen Datei verarbeiten. Es sollte keinen Speicher verbrauchen, bis Sie nach der Rückgabe der Daten gefragt haben. Versuchen Sie herauszufinden, ob die Verzögerung die Anforderung erfüllt oder ob die Daten heruntergeladen werden.

Aus den Geräuschen heraus können Sie die Datenbank abstrahieren und Pandas die Anfragen stellen lassen. Es könnte sich lohnen, zu prüfen, wie die Ergebnisse eingeschränkt werden. Sie sollten die Anforderung für alle Daten durchführen können, aber die Ergebnisse nur Zeile für Zeile vom Datenbankserver laden.