Umgang mit riesigen SQL-Resultsets

9

Ich arbeite mit einer ziemlich großen MySQL-Datenbank (mehrere Millionen Zeilen) mit einer Spalte, die Blob-Bilder speichert. Die Anwendung versucht, eine Teilmenge der Bilder aufzunehmen und einige Verarbeitungsalgorithmen auf ihnen auszuführen. Das Problem, auf das ich stoße, ist, dass das Dataset, das meine Abfrage zurückgibt, aufgrund des ziemlich großen Datasets, das ich zurückgeben möchte, zu groß ist, um es im Speicher zu speichern.

Vorläufig habe ich die Abfrage geändert, um die Bilder nicht zurückzugeben. Während ich über die Ergebnismenge iteriere, führe ich eine andere Auswahl aus, die das einzelne Bild, das sich auf den aktuellen Datensatz bezieht, ergreift. Das funktioniert, aber die Zehntausende von zusätzlichen Abfragen haben zu einem Leistungsabfall geführt, der inakzeptabel ist.

Meine nächste Idee besteht darin, die ursprüngliche Abfrage auf 10.000 Ergebnisse oder so zu beschränken und dann Abfragen über Spannen von 10.000 Zeilen durchzuführen. Dies scheint der Kompromiss zwischen den beiden Ansätzen zu sein. Ich denke, dass es wahrscheinlich eine bessere Lösung gibt, die mir nicht bewusst ist. Gibt es eine andere Möglichkeit, nur Teile eines gigantischen Resultsets gleichzeitig im Speicher zu haben?

Prost,

Dave McClelland

    
Dave McClelland 26.03.2010, 00:03
quelle

4 Antworten

3

Eine Option ist die Verwendung eines DataReaders. Es streamt die Daten, aber es geht darum, eine offene Verbindung zur Datenbank aufrechtzuerhalten. Wenn Sie über mehrere Millionen Zeilen iterieren und die Verarbeitung für jeden einzelnen durchführen, ist das unter Umständen nicht wünschenswert.

Ich denke, Sie sind auf dem richtigen Weg, die Daten in Chunks zu packen, wahrscheinlich mit MySqls Limit-Methode, richtig?

    
Anthony Pegram 26.03.2010, 00:15
quelle
1

Wenn Sie mit so großen Datensätzen arbeiten, ist es wichtig, dass Sie nicht alle auf einmal im Speicher haben müssen. Wenn Sie das Ergebnis auf die Festplatte oder auf eine Webseite schreiben, tun Sie dies, während Sie in jeder Zeile lesen. Warten Sie nicht, bis Sie alle Zeilen gelesen haben, bevor Sie mit dem Schreiben beginnen.

Sie könnten die Bilder auch auf DelayLoad = true setzen, so dass sie nur abgerufen werden, wenn Sie sie benötigen, anstatt diese Funktionalität selbst zu implementieren. Weitere Informationen finden Sie hier .

    
Mark Byers 26.03.2010 00:06
quelle
0

Ich sehe 2 Optionen.

1) Wenn es sich um eine Windows-App (im Gegensatz zu einer Webanwendung) handelt, können Sie jedes Bild mit einem Datenlesegerät lesen und die Datei in einen temporären Ordner auf der Festplatte kopieren die physische Datei.

2) Lesen und verarbeiten Sie die Daten in kleinen Blöcken. 10k Zeilen können immer noch sehr viel sein, abhängig davon, wie groß die Bilder sind und wie viel Prozess Sie tun möchten. Die Rückgabe von 5k Zeilen gleichzeitig und das Lesen von mehr in einem separaten Thread, wenn Sie bis zu 1k verbleiben, um noch zu verarbeiten, können für einen nahtlosen Prozess sorgen.

Auch wenn dies nicht immer empfohlen wird, kann das Erzwingen der Speicherbereinigung vor der Verarbeitung des nächsten Satzes von Zeilen helfen, Speicher freizugeben.

    
ProphetBeal 26.03.2010 01:20
quelle
0

Ich habe eine Lösung wie die in diesem Tutorial beschriebene verwendet: Ссылка

Sie könnten Multi-Threading verwenden, um einen Teil der nächsten Datensätze vorzuziehen (zuerst ziehen Sie 1-10.000 und im Hintergrund ziehen Sie 10.001 - 20.000 und 20.001-30.000 Zeilen und löschen die vorherigen Seiten der Daten ( Sagen Sie, wenn Sie bei 50.000 bis 60.000 sind, löschen Sie die ersten 1-10.000 Zeilen, um Speicher zu sparen, wenn das ein Problem ist.) Und verwenden Sie den Standort des Benutzers der aktuellen "Seite" als Zeiger, um den nächsten Datenbereich zu ziehen oder einige Daten zu löschen. von Bereichsdaten.

    
Gary 26.03.2010 19:53
quelle

Tags und Links