Optimización de consultas de Django ORM
El ORM de Django facilita el trabajo con la base de datos. Pero esconde un peligro. Si recuperas objetos relacionados de forma ineficiente, creas el problema de las consultas N+1.
Esto significa que si recuperas 100 posts, tu aplicación podría ejecutar 101 consultas. Esto ralentiza tu aplicación hasta detenerla.
Usa estas dos herramientas para solucionarlo:
- select_related
Úsalo para ForeignKey y OneToOneField.
Utiliza un SQL JOIN. Obtiene los datos relacionados en una sola consulta.
- Ejemplo: Post tiene un Author.
- Forma ingenua: 101 consultas para 100 posts.
- Forma optimizada: 1 consulta usando .select_related("author").
- prefetch_related
Úsalo para ManyToManyField y ForeignKeys inversas.
Ejecuta consultas separadas y las une en Python.
- Ejemplo: Post tiene muchos Tags.
- Forma ingenua: 1 consulta para los posts + 1 consulta por cada uno de los tags de cada post.
- Forma optimizada: 2 consultas en total usando .prefetch_related("tags").
Consejos profesionales:
- Usa el objeto Prefetch para filtrar los datos relacionados antes de que lleguen a tu bucle.
- Encadénalos. Puedes usar ambos en un mismo queryset para obtener autores y etiquetas a la vez.
- Evita llamar a .filter() en una relación con prefetch dentro de un bucle. Esto ignora la caché y vuelve a consultar la base de datos.
- Usa .only() con select_related para recuperar solo las columnas que necesitas.
Resumen:
- ForeignKey / OneToOne: Usa select_related.
- ManyToMany / Reverse FK: Usa prefetch_related.
Comprueba el número de consultas con django-debug-toolbar para detectar estos problemas a tiempo.