Die meisten DBAPI-Implementierungen puffern Zeilen beim Abrufen vollständig. In der Regel befindet sich die gesamte Ergebnismenge im Speicher, bevor das SQLAlchemy-ORM überhaupt ein Ergebnis erhält.
Die Funktionsweise Query
besteht jedoch darin, dass die angegebene Ergebnismenge standardmäßig vollständig geladen wird, bevor Ihre Objekte an Sie zurückgegeben werden. Die Begründung bezieht sich hier auf Abfragen, die mehr als einfache SELECT-Anweisungen sind. Beispielsweise muss bei Verknüpfungen mit anderen Tabellen, die möglicherweise dieselbe Objektidentität mehrmals in einer Ergebnismenge zurückgeben (häufig beim eifrigen Laden), der gesamte Satz von Zeilen im Speicher gespeichert werden, damit die korrekten Ergebnisse zurückgegeben werden können, andernfalls Sammlungen und dergleichen möglicherweise nur teilweise besiedelt.
Bietet also Query
eine Möglichkeit, dieses Verhalten durch zu ändern yield_per()
. Dieser Aufruf bewirkt, dass die Query
Zeilen in Stapeln ausgegeben werden, in denen Sie die Stapelgröße angeben. Wie in den Dokumenten angegeben, ist dies nur dann angebracht, wenn Sie keine eifrigen Sammlungen laden. Wenn Sie also wirklich wissen, was Sie tun. Wenn das zugrunde liegende DBAPI Zeilen vorpuffert, bleibt der Speicheraufwand bestehen, sodass der Ansatz nur geringfügig besser skaliert als nicht verwendet wird.
Ich benutze es kaum yield_per()
; Stattdessen verwende ich eine bessere Version des oben vorgeschlagenen LIMIT-Ansatzes mit Fensterfunktionen. LIMIT und OFFSET haben das große Problem, dass sehr große OFFSET-Werte dazu führen, dass die Abfrage immer langsamer wird, da ein OFFSET von N dazu führt, dass sie durch N Zeilen blättert - es ist, als würde sie jedes Mal fünfzig Mal eine Abfrage ausführen, anstatt eine immer größere Anzahl von Zeilen. Bei einem Fensterfunktionsansatz rufe ich eine Reihe von "Fenster" -Werten vorab ab, die sich auf Teile der Tabelle beziehen, die ich auswählen möchte. Ich gebe dann einzelne SELECT-Anweisungen aus, die jeweils aus einem dieser Fenster gleichzeitig abgerufen werden.
Der Fensterfunktionsansatz befindet sich im Wiki und ich benutze ihn mit großem Erfolg.
Beachten Sie auch: Nicht alle Datenbanken unterstützen Fensterfunktionen. Sie benötigen Postgresql, Oracle oder SQL Server. IMHO mit mindestens Postgresql lohnt sich auf jeden Fall - wenn Sie eine relationale Datenbank verwenden, können Sie auch die beste verwenden.