Estoy creando un servicio que necesita para mantener algo en la línea de un sistema de seguimiento de casos. Aquí es nuestro modelo:rendimiento de django al consultar modelos con muchas claves externas?
class Incident(models.Model):
title = models.CharField(max_length=128)
category = models.ForeignKey(Category)
status = models.ForeignKey(Status)
severity = models.ForeignKey(Severity)
owned_by = models.ForeignKey(User, related_name="owned_by", null=True, blank=True)
next_action = models.ForeignKey(IncidentAction)
created_date = models.DateTimeField()
created_by = models.ForeignKey(User, related_name="opened_by")
last_edit_date = models.DateTimeField(null=True, blank=True)
last_edit_by = models.ForeignKey(User, related_name="last_edit_by", null=True, blank=True)
closed_date = models.DateTimeField(null=True, blank=True)
closed_by = models.ForeignKey(User, related_name="Closed by", null=True, blank=True)
Debido a que hay una gran cantidad de claves externas que se tira en este modelo, lo hace para consultas SQL interesantes. Hemos estado utilizando como prueba el djblets data grid y la barra de herramientas de depuración django, y estamos alarmados por la cantidad de consultas que se golpean cada vez que agregamos una nueva columna para ver que usa una clave externa, básicamente hace este tipo de flujo de trabajo de consulta :
#prepare the grid
select * from incident_table;
#render each row
for each row in incident table
for each column that is a foreign key select row from foreign table with id
Se hace un consulta de selección adicional por fila para cada columna que intenta tirar de una propiedad de una clave externa.
Estoy pensando que este es un problema universal con django y su ORM con respecto a extraer propiedades de los modelos de clave externa para su visualización. Como prueba, dejé caer la cuadrícula de datos y acabo de hacer una lista simple de propiedades para un conjunto de consulta, y vi que las consultas aumentaban de forma similar.
Queremos ampliar esto con la gran cantidad de usuarios que utilizan el modelo. Como comparación, hice una vista similar del modelo de usuario, y su visualización completa se acaba de hacer con una consulta, porque si solo extraes campos del modelo dado, no se obtiene un hit de db adicional por columna adicional.
Algunas optimizaciones que probamos eran:
- django-orm-cache: no parece trabajar con Django 1.0.4
- django-caching: Esto funciona bien para el almacenamiento en caché el tantas veces preguntó modelos
- vista caché de nivel memcached
- Editar: usando select_related() puede acelerar la representación de la plantilla al no tener un viaje de ida y vuelta a la base de datos, pero parece que sigue las teclas foráneas solo una tiempo de espera en el conjunto de consulta original utilizando la única consulta por clave externa. Simplemente parece mover el resultado de la consulta de la base de datos múltiple antes de tiempo.
Pero hay algunas preguntas más profundas que estamos solicitando la sabiduría de la multitud:
- Para los modelos con toneladas de claves externas, ¿cuál es la mejor manera de hacerlo de manera eficiente consulta para obtener propiedades de claves extranjeras?
- ¿El almacenamiento en caché de los modelos dependientes es la única manera de utilizar los sistemas de caché ORM anteriores?
- ¿O se trata de un caso estándar de crecimiento del ORM y la necesidad de lanzar nuestra propia consulta SQL personalizada con combinaciones para obtener la salida de cuadrícula de datos deseada de la manera más eficiente posible?
preguntas relacionadas que aumentaron las preocupaciones sobre el almacenamiento en caché y las claves externas:
DB/performance: layout of django model that rarely refers to its parent more than once, Django ORM: caching and manipulating ForeignKey objects:
Ah, sí. Me encuentro muy corregido: parece que la cuadrícula de datos está ignorando las optimizaciones proporcionadas por el conjunto de firmas proporcionado y realiza sus propias búsquedas. Las pruebas independientes de mi modelo con su ejemplo hicieron que los beneficios de select_related() fueran tan claros como el día. ¡Gracias! – dmyung