sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Por qué la iteración a través de un Django QuerySet grande consume grandes cantidades de memoria?

Nate C estuvo cerca, pero no del todo.

De los documentos:

Puede evaluar un QuerySet de las siguientes maneras:

  • Iteración. Un QuerySet es iterable y ejecuta su consulta de base de datos la primera vez que lo itera. Por ejemplo, esto imprimirá el título de todas las entradas en la base de datos:

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

Entonces, sus diez millones de filas se recuperan, todas a la vez, cuando ingresa por primera vez a ese ciclo y obtiene la forma iterativa del conjunto de consultas. La espera que experimenta es que Django carga las filas de la base de datos y crea objetos para cada una, antes de devolver algo sobre lo que realmente puede iterar. Entonces tienes todo en la memoria y los resultados se derraman.

De mi lectura de los documentos, iterator() no hace nada más que eludir los mecanismos de almacenamiento en caché internos de QuerySet. Creo que podría tener sentido que hiciera algo uno por uno, pero eso requeriría diez millones de visitas individuales a su base de datos. Tal vez no sea tan deseable.

La iteración sobre grandes conjuntos de datos de manera eficiente es algo que todavía no hemos entendido del todo bien, pero hay algunos fragmentos que pueden resultarle útiles para sus propósitos:

  • Iterador Django QuerySet eficiente en memoria
  • conjuntos de consultas por lotes
  • Conjunto de consultas para cada uno