2011-10-31 95 views
7

Django注释非常适合平均值,最小/最大值等,它也可以计数。那么它是否会生成相同的SQL,就像我在查询集上使用旧的.count()一样?或者它在某些情况下生成更高效的SQL?还是更糟糕的SQL?在django中,是否聚合(Count())比.count()更快或更好?

对不起,澄清,我打算比较count()操作与像聚合(计数('id'))其中id是表的PK。

因此,我相信Brian有正确的答案。简而言之,count()只是aggregate()的一个特例。

回答

8

调用查询集的.count()方法最终调用Count()

具体来说: django.db.models.QuerySet.count()呼叫 django.db.models.sql.Query.get_count(),它调用 django.db.models.sql.Query.add_count_column(),这增加 django.db.models.sql.aggregates.Count到查询中。

两者之间的主要区别是,当你直接使用Count,你指定你要计算,而当你在查询集调用.count(),这将导致SELECT COUNT(*)...(除非你也可以使用不同的字段()或者当你限制select子句中的字段时,在这种情况下它会更复杂)。

1

苹果和橘子。 .count()对当前查询集执行SQL计数。但是,集合Count会对您在查询集上指定的关系进行计数。

Pizza.objects.count() # Total amount of pizzas 

Pizza.objects.aggregate(topping_count=Count('toppings')) # Total amount of toppings associated to a pizza 

Pizza.objects.annotate(topping_count=Count('toppings')) # Total amount of toppings on each pizza 
+0

假设Pizza和Topping有一个m2m的关系,在第二行中调用比萨的聚合将不会返回每个比萨的配料总数;它会将Pizza加入Topping并基本统计联接的数量。要获得每个披萨的配料数量,您需要使用annotate()而不是aggreate()。 –

+0

对不起。我没有描述聚合返回的内容。更新描述并添加'注释'版本以突出显示差异 –

+0

如果一个打顶连接到多个比萨饼,它将会在'Pizza.objects.aggregate(topping_count = Count('toppings'))中加入到多个比萨饼中'因此这个计数将返回比配料的总数量多。为了得到与匹萨相关的配料总数(没有重复计数),你可能想要做一些类似于“Topping.objects.exclude(pizza_set = None).count()'。 –