Django中的多联接查询

时间:2020-03-05 18:56:01  来源:igfitidea点击:

在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方法,该方法允许添加自定义联接。