Nate C był blisko, ale nie do końca.
Z dokumentów:
Możesz ocenić QuerySet w następujący sposób:
-
Iteracja. QuerySet jest iterowalny i wykonuje zapytanie do bazy danych przy pierwszej iteracji. Na przykład spowoduje to wydrukowanie nagłówka wszystkich wpisów w bazie danych:
for e in Entry.objects.all(): print e.headline
Więc twoje dziesięć milionów wierszy jest pobieranych jednocześnie, kiedy po raz pierwszy wchodzisz do tej pętli i otrzymujesz iteracyjną formę zestawu zapytań. Czekanie, którego doświadczasz, polega na tym, że Django ładuje wiersze bazy danych i tworzy obiekty dla każdego z nich, zanim zwróci coś, nad czym możesz iterować. Wtedy masz wszystko w pamięci, a wyniki się wylewają.
Z mojego czytania dokumentów, iterator()
nie robi nic więcej niż ominięcie wewnętrznych mechanizmów buforowania QuerySet. Myślę, że może to mieć sens, aby zrobić jedną rzecz jeden po drugim, ale to z kolei wymagałoby dziesięciu milionów pojedynczych trafień w twojej bazie danych. Może nie aż tak pożądane.
Wydajne iterowanie dużych zestawów danych to coś, czego wciąż nie dopracowaliśmy, ale istnieją pewne fragmenty, które mogą okazać się przydatne do Twoich celów:
- Iterator Django QuerySet z wydajną pamięcią
- wsadowe zestawy zapytań
- QuerySet Foreach