sql >> Base de Datos >  >> RDS >> Mysql

iterador/generador de SqlAlchemy incorporado eficiente en memoria?

La mayoría de las implementaciones de DBAPI almacenan completamente las filas a medida que se recuperan, por lo que, por lo general, antes de que SQLAlchemy ORM 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 consultas que son más que simples declaraciones SELECT. Por ejemplo, en 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 se puedan devolver los resultados correctos; de lo contrario, las colecciones y similares podría estar solo parcialmente poblado.

Entonces Query ofrece una opción para cambiar este comportamiento a través de yield_per() . Esta llamada generará la Query para producir 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 es básicamente si realmente sabe lo que está haciendo. Además, si la DBAPI subyacente almacena previamente en búfer las filas, aún habrá esa sobrecarga de memoria, por lo que el enfoque solo se escala un poco mejor que no usarlo.

Casi nunca uso yield_per(); en su lugar, utilizo una mejor versión del enfoque LIMIT que sugiere anteriormente usando funciones de ventana. LIMIT y OFFSET tienen el gran problema de que los valores de DESPLAZAMIENTO muy grandes hacen que la consulta se vuelva cada vez más lenta, ya que un DESPLAZAMIENTO de N hace que se desplace a través de N filas; es como hacer la misma consulta cincuenta veces en lugar de una, cada vez que se lee un mayor y mayor número de filas. Con un enfoque de función de ventana, busco previamente un conjunto de valores de "ventana" que se refieren a partes de la tabla que quiero seleccionar. Luego emito instrucciones SELECT individuales que cada una extrae de una de esas ventanas a la vez.

El enfoque de la función de ventana es 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.