Większość implementacji DBAPI w pełni buforuje wiersze podczas ich pobierania - tak więc zwykle, zanim SQLAlchemy ORM nawet zatrzyma jeden wynik, cały zestaw wyników jest w pamięci.
Ale sposób Query
działa tak, że w pełni ładuje podany zestaw wyników domyślnie przed zwróceniem do ciebie twoich obiektów. Uzasadnienie tutaj dotyczy zapytań, które są czymś więcej niż prostymi instrukcjami SELECT. Na przykład, w połączeniach z innymi tabelami, które mogą zwracać tę samą tożsamość obiektu wiele razy w jednym zestawie wyników (często w przypadku zachłannego ładowania), pełny zestaw wierszy musi znajdować się w pamięci, aby można było zwrócić poprawne wyniki, w przeciwnym razie kolekcje itp. może być tylko częściowo zaludniony.
Query
Oferuje więc opcję zmiany tego zachowania za pomocą yield_per()
. To wywołanie spowoduje, że będzie Query
generować wiersze w partiach, jeśli podasz rozmiar partii. Jak stwierdza dokumentacja, jest to właściwe tylko wtedy, gdy nie wykonujesz żadnego gorliwego ładowania kolekcji, więc w zasadzie jest to, jeśli naprawdę wiesz, co robisz. Ponadto, jeśli bazowy DBAPI wstępnie buforuje wiersze, nadal będzie ten narzut pamięci, więc podejście skaluje się tylko nieco lepiej niż nieużywanie go.
Rzadko kiedy używam yield_per()
; zamiast tego używam lepszej wersji podejścia LIMIT, które sugerujesz powyżej, używając funkcji okna. LIMIT i OFFSET mają ogromny problem, ponieważ bardzo duże wartości OFFSET powodują, że zapytanie staje się wolniejsze i wolniejsze, ponieważ OFFSET o N powoduje, że przegląda N wierszy - to tak, jakby wykonać to samo zapytanie pięćdziesiąt razy zamiast jednego, za każdym razem, gdy czytasz coraz większa liczba rzędów. Stosując podejście funkcji okna, wstępnie pobieram zestaw wartości „okna”, które odnoszą się do fragmentów tabeli, które chcę zaznaczyć. Następnie emituję indywidualne instrukcje SELECT, które są pobierane z jednego z tych okien na raz.
Podejście do funkcji okna jest na wiki i używam go z wielkim sukcesem.
Uwaga: nie wszystkie bazy danych obsługują funkcje okien; potrzebujesz Postgresql, Oracle lub SQL Server. IMHO używając przynajmniej Postgresql jest zdecydowanie tego warte - jeśli korzystasz z relacyjnej bazy danych, równie dobrze możesz użyć najlepszych.