Django中的多联接查询
在Django中使用ORM和QuerySet API进行多联接查询的最佳和/或者最快方法是什么?
解决方案
回答
如果尝试跨由ForeignKeys或者ManyToManyField关系链接的表进行联接,则可以使用双下划线语法。例如,如果我们具有以下模型:
class Foo(models.Model): name = models.CharField(max_length=255) class FizzBuzz(models.Model): bleh = models.CharField(max_length=255) class Bar(models.Model): foo = models.ForeignKey(Foo) fizzbuzz = models.ForeignKey(FizzBuzz)
我们可以执行以下操作:
Fizzbuzz.objects.filter(bar__foo__name = "Adrian")
回答
不要使用API ;-)严重的是,如果JOIN很复杂,则应该通过使用SQL而不是使用API来显着提高性能。这并不意味着我们需要在所有漂亮的Python代码中都弄脏了SQL。只需让一个自定义管理器来处理JOIN,然后让其余代码使用它,而不是直接使用SQL。
另外,我在DjangoCon上,他们举办了一次有关高性能Django的研讨会,而我从中获得的关键优势之一是,如果性能是一个真正的关注点(并且我们计划有一天有大量流量),那么我们真的首先不应该进行JOIN,因为它们使扩展应用程序同时保持良好性能几乎是不可能的。
这是Google演讲的视频:
http://www.youtube.com/watch?v=D-4UN4MkSyI&feature=PlayList&p=D415FAF806EC47A1&index=20
当然,如果我们知道应用程序将永远不必处理这种扩展问题,请加入:-)并且,如果我们也不必担心使用API会对性能造成的影响,那么我们真的不需要我们不必担心(AFAIK)的微小问题(如果有的话),即使用一种API方法与使用另一种API方法之间的性能差异。
只需使用:
http://docs.djangoproject.com/en/dev/topics/db/queries/#lookups-that-span-relationships
希望能有所帮助(如果没有,希望某些真正的Django黑客可以加入并解释为什么方法X实际上确实有一些明显的性能差异)。
回答
请使用queryset.query.join方法,但前提是此处所述的其他方法(使用双下划线)不足够。
回答
Caktus博客对此有一个答案:http://www.caktusgroup.com/blog/2009/09/28/custom-joins-with-djangos-queryjoin/
基本上,有一个隐藏的QuerySet.query.join方法,该方法允许添加自定义联接。