2011-03-24 70 views
11

在与同行讨论N + 1以及严重的数据库查询性能问题后,我访问了http://guides.rubyonrails.org/active_record_querying.htmlDjango N + 1查询解决方案

的ActiveRecord(导轨):

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

如果客户有地址,我打算访问它们,同时通过客户端循环,Rails提供includes,让它知道先走,并把它们添加到查询,从而消除了9次查询。

Django的:

https://github.com/lilspikey/django-batch-select提供批量查询的支持。你知道其他图书馆或技巧来实现上面Rails提供的,但是在一个不太冗长的庄园中(就像19个字符修复N + 1并且非常清晰的rails例子)?另外,批处理选择是以同样的方式解决问题还是这两个不同的东西?

顺便说一句,我没有问关于select_related,虽然它可能乍一看似乎是答案。我正在谈到addressclient有一个外键的情况。

回答

9

不幸的是,Django的ORM还没有办法做到这一点。

幸运的是,只需要2个查询就可以完成它,只需要在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

谢谢。顺便说一句,这将创建一个查询的效率(即,Rails可能做什么神奇的提供更好的性能,或者他们可能只是语法糖为同一事物)?显然,如果所有事情都不需要马上评估,那么它会更好,但也许他们也是这样做的。 – orokusaki 2011-03-24 18:26:07

+0

我不知道。它*可以在一个查询中执行动作,但这需要Django的ORM还没有的一定程度的欺骗。 – 2011-03-24 18:28:12

+0

好的。再次感谢。 – orokusaki 2011-03-24 18:29:12

2

django-batch-select应该提供这个问题的答案,虽然我还没有尝试过。伊格纳西奥的回答对我来说似乎是最好的。