PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Perché l'iterazione di un QuerySet di Django di grandi dimensioni consuma enormi quantità di memoria?

Nate C era vicino, ma non del tutto.

Dai documenti:

Puoi valutare un QuerySet nei seguenti modi:

  • Iterazione. Un QuerySet è iterabile ed esegue la query del database la prima volta che si esegue un'iterazione su di esso. Ad esempio, questo stamperà il titolo di tutte le voci nel database:

    for e in Entry.objects.all():
        print e.headline
    

Quindi i tuoi dieci milioni di righe vengono recuperati, tutto in una volta, quando entri per la prima volta in quel ciclo e ottieni la forma iterativa del set di query. L'attesa che si verifica è Django che carica le righe del database e crea oggetti per ognuna, prima di restituire qualcosa su cui puoi effettivamente scorrere. Quindi hai tutto in memoria e i risultati vengono fuori.

Dalla mia lettura dei documenti, iterator() non fa altro che bypassare i meccanismi di memorizzazione nella cache interna di QuerySet. Penso che potrebbe avere senso che faccia una cosa una per una, ma ciò richiederebbe al contrario dieci milioni di hit individuali sul tuo database. Forse non del tutto desiderabile.

L'iterazione efficiente di set di dati di grandi dimensioni è qualcosa che non abbiamo ancora capito bene, ma ci sono alcuni frammenti che potresti trovare utili per i tuoi scopi:

  • Iteratore Django QuerySet efficiente in termini di memoria
  • serie di query in batch
  • QuerySet Foreach