2011-03-24 20 views
11

Visité http://guides.rubyonrails.org/active_record_querying.html después de hablar con un par con respecto a N + 1 y las graves implicaciones de rendimiento de consultas DB incorrectas.Solución de consulta Django N + 1

ActiveRecord (rieles):

clients = Client.includes(:address).limit(10) 

Dónde cliente a tener direcciones, y tengo la intención de acceder a ellos, mientras que bucle a través de los clientes, rieles proporciona includes para hacerle saber a seguir adelante y añadirlos a la consulta, que elimina 9 consultas al instante.

Django:

https://github.com/lilspikey/django-batch-select proporciona soporte consulta por lotes. ¿Conoces otras bibliotecas o trucos para lograr lo que Rails proporciona más arriba, pero en una casa solariega menos detallada (como en el ejemplo de rieles en el que solo 19 caracteres fijan N + 1 y es muy claro)? Además, ¿la selección de lotes aborda la preocupación de la misma manera, o son estas dos cosas diferentes?

Por cierto, no estoy preguntando acerca de select_related, aunque puede parecer la respuesta a primera vista. Estoy hablando de una situación en la que address tiene una clave de forign para client.

Respuesta

9

Desafortunadamente, el ORM de Django aún no tiene forma de hacerlo.

Afortunadamente, es posible hacerlo en solo 2 consultas, con un poco de trabajo realizado en Python.

clients = list(Client.objects.all()[:10]) 
addresses = dict((x.client_id, x) for x in 
    Address.objects.filter(client__in=clients)) 
for client in clients: 
    print client, addresses[client.id] 
+0

gracias. Por cierto, ¿creará eso una consulta tan eficiente (es decir, si Rails está haciendo algo mágico que proporcione un mejor rendimiento, o probablemente sea solo azúcar sintáctica para la misma cosa)? Obviamente, sería mejor si no hubiera que evaluar todo en la memoria de inmediato, pero tal vez la suya también lo esté haciendo. – orokusaki

+0

No lo sé. Es * posible * realizar la acción en una consulta, pero eso requiere un nivel de engaño que el ORM de Django aún no posee. –

+0

bien. Gracias de nuevo. – orokusaki

2

django-batch-select se supone que es dar una respuesta a este problema, aunque yo no lo he probado. La respuesta de Ignacio arriba me parece mejor.

Cuestiones relacionadas