Większość implementacji DBAPI w pełni buforuje wiersze podczas ich pobierania - więc zwykle, zanim SQLAlchemy ORM otrzyma nawet jeden wynik, cały zestaw wyników znajduje się w pamięci.
Ale potem sposób Query
działa to, że domyślnie w pełni ładuje podany zestaw wyników przed powrotem do twoich obiektów. Uzasadnienie dotyczy tutaj zapytań, które są czymś więcej niż prostymi instrukcjami SELECT. Na przykład w sprzężeniach do innych tabel, które mogą wielokrotnie zwracać tę samą tożsamość obiektu w jednym zestawie wyników (często przy gorliwym ładowaniu), pełny zestaw wierszy musi znajdować się w pamięci, aby można było zwrócić poprawne wyniki, w przeciwnym razie kolekcje i takie może być tylko częściowo zaludniony.
Więc Query
oferuje opcję zmiany tego zachowania za pomocą yield_per()
. To wywołanie spowoduje Query
aby uzyskać wiersze w partiach, w których podajesz rozmiar partii. Jak stwierdzają w dokumentacji, jest to właściwe tylko wtedy, gdy nie wykonujesz żadnego gorliwego ładowania kolekcji, więc jest to po prostu wtedy, gdy naprawdę wiesz, co robisz. Ponadto, jeśli bazowe wiersze buforów wstępnych DBAPI nadal będą występować w pamięci, więc podejście skaluje się tylko nieco lepiej niż nieużywanie go.
Rzadko 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 polegający na tym, że bardzo duże wartości OFFSET powodują, że zapytanie staje się coraz wolniejsze, ponieważ PRZESUNIĘCIE równe N powoduje przejście przez N wierszy - to tak, jakby wykonać to samo zapytanie pięćdziesiąt razy zamiast jednego, za każdym razem czytając coraz większa liczba rzędów. W podejściu do funkcji okna pobieram wstępnie zestaw wartości „okna”, które odnoszą się do fragmentów tabeli, którą chcę wybrać. Następnie emituję indywidualne instrukcje SELECT, z których każda pobierana jest 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ący przynajmniej Postgresql jest zdecydowanie tego wart - jeśli używasz relacyjnej bazy danych, równie dobrze możesz użyć najlepszych.