Quiero iterar todos los objetos de una tabla (Publicar) que estoy usando el siguiente código:
posts = Post.objects.all() for post in posts: process_post(post) process_post es una tarea de apio que se ejecutará en segundo plano y no se actualizará. Pero el problema que tengo es que la tabla Post tiene 1 millón de registros. Este no es un trabajo de una sola vez. Lo ejecuto a diario.
for post in postsEn la línea anterior, se llama Query, que obtiene todos los datos de la base de datos de una sola vez.
¿Cómo puedo mejorar su rendimiento? ¿Hay alguna forma de obtener los datos en lotes?
Haz tu propio iterator . Por ejemplo, digamos 1 million registros.
count = Post.objects.all().count() #1 million chunk_size = 1000 for i in range(0, count, chunk_size): posts = Post.objects.all()[i:i+chunk_size] for post in posts: process_post(post) Rebanar en queryset reproducirá usos LIMIT , OFFSET . La consulta puede disminuir según el aumento de chunk_size , mientras que el uso de la memoria también aumenta. Optimícelo para su caso de uso.
Mi primera sugerencia sería usar select_related o prefetch_related. Revise la documentación de django e infórmese al respecto. Debería solucionar su problema. Pero como ha dicho, tiene algunos millones de registros para esa tabla. Iterar a través de ellos siempre será un negocio costoso. La mejor solución es optar por un procedimiento almacenado si el método process_post está tardando. Puede lograr su objetivo con solo una solicitud a su base de datos en lugar de millones de llamadas de base de datos en el bucle.
Django no se utiliza para procesar los datos. este es solo un marco para hacer API y ORM para frontend.
puede limitar el proceso dependiendo de su memoria y base de datos como obj = post.objects.all()[30000] etc o 50000
si desea mostrar en HTML front-end, use la paginación
si desea un proceso en el backend, no use Django ORM. en la base de datos, haga una vista materlizada y un trabajo de base de datos (esto es muy fácil en la base de datos de Oracle)