13

在与同行讨论 N+1 以及不良数据库查询对性能的严重影响后,我访问了http://guides.rubyonrails.org/active_record_querying.html 。

活动记录(轨道):

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

如果客户端有地址,并且我打算在遍历客户端时访问它们,Rails 提供includes了让它知道继续并将它们添加到查询中,这样一来就消除了 9 个查询。

姜戈:

https://github.com/lilspikey/django-batch-select提供批量查询支持。您是否知道其他库或技巧来实现 Rails 提供的上述功能,但不那么冗长(如在 rails 示例中,其中只有 19 个字符修复 N+1 并且非常清楚)?另外,批处理选择是否以相同的方式解决了这个问题,还是这两个不同的东西?

顺便说一句,我不是在问select_related,尽管乍一看似乎是答案。我说的是address有一个外键的情况client

4

3 回答 3

13

自 Django 1.4 起,您可以使用 prefetch_related 来做到这一点: https ://docs.djangoproject.com/en/dev/ref/models/querysets/#prefetch-related

如果您使用的是 < 1.4,请查看此模块: https ://github.com/ionelmc/django-prefetch

它声称比 Django 的 prefetch_related 更灵活。冗长但效果很好。

于 2013-01-21T03:24:16.573 回答
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]
于 2011-03-24T16:22:57.577 回答
2

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

于 2011-11-11T17:41:45.967 回答