La mayoría de las implementaciones de DBAPI almacenan en búfer las filas a medida que se obtienen; por lo general, antes de que el ORM de SQLAlchemy obtenga un resultado, todo el conjunto de resultados está en la memoria.
Pero entonces, la forma en que Query
funciona es que carga completamente el conjunto de resultados dado de forma predeterminada antes de devolverle sus objetos. El fundamento aquí se refiere a las consultas que son más que simples declaraciones SELECT. Por ejemplo, en las uniones a otras tablas que pueden devolver la misma identidad de objeto varias veces en un conjunto de resultados (común con la carga ansiosa), el conjunto completo de filas debe estar en la memoria para que los resultados correctos se puedan devolver, de lo contrario, colecciones y tal podría estar solo parcialmente poblado.
Entonces Query
ofrece una opción para cambiar este comportamiento a través de yield_per()
. Esta llamada hará Query
que produzca filas en lotes, donde le da el tamaño del lote. Como dicen los documentos, esto solo es apropiado si no está haciendo ningún tipo de carga ansiosa de colecciones, por lo que básicamente es si realmente sabe lo que está haciendo. Además, si el DBAPI subyacente almacena previamente las filas en el búfer, seguirá existiendo esa sobrecarga de memoria, por lo que el enfoque solo se escala ligeramente mejor que no usarlo.
Casi nunca lo uso yield_per()
; en cambio, utilizo una mejor versión del enfoque LIMIT que sugieres anteriormente usando funciones de ventana. LIMIT y OFFSET tienen un gran problema de que los valores de OFFSET muy grandes hacen que la consulta se vuelva cada vez más lenta, ya que un OFFSET de N hace que recorra N filas; es como hacer la misma consulta cincuenta veces en lugar de una, cada vez que lee un mayor y mayor número de filas. Con un enfoque de función de ventana, obtengo previamente un conjunto de valores de "ventana" que se refieren a partes de la tabla que quiero seleccionar. Luego emito declaraciones SELECT individuales que cada una extrae de una de esas ventanas a la vez.
El enfoque de la función de ventana está en la wiki y lo uso con gran éxito.
También tenga en cuenta: no todas las bases de datos admiten funciones de ventana; necesita Postgresql, Oracle o SQL Server. En mi humilde opinión, usar al menos Postgresql definitivamente vale la pena: si está usando una base de datos relacional, también podría usar la mejor.