【问题标题】:In django, is aggregate(Count()) faster or better than .count() in anyway?在 django 中,aggregate(Count()) 是否比 .count() 更快或更好?
【发布时间】:2011-12-18 22:40:10
【问题描述】:

Django 注释非常适用于平均值、最小值/最大值等。它也可以计数。那么这是否会生成与我在查询集上使用旧的 .count() 相同的 SQL?还是在某些情况下它会生成更高效的 SQL?还是更糟糕的 SQL?

抱歉,澄清一下,我的意思是将 count() 操作与类似 aggregate(Count('id')) 的操作进行比较,其中 id 是表的 PK。

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

【问题讨论】:

    标签: django


    【解决方案1】:

    调用查询集的.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(*)...(除非你也可以使用 distinct() 或限制 select 子句中的字段,在这种情况下会更复杂)。

    【讨论】:

      【解决方案2】:

      苹果和橙子。 .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
      

      【讨论】:

      • 假设 Pizza 和 Topping 具有 m2m 关系,在第二行中调用 Pizza 上的聚合将不会返回每个 Pizza 的浇头总数;它会将 Pizza 外连接到 Topping 并基本上计算连接数。要获取每个比萨饼的浇头数量,您需要使用 annotate() 而不是 agreate()。
      • 对不起。我对聚合返回的内容的描述不正确。更新描述并添加annotate版本以突出差异
      • 如果一个浇头与一个以上的比萨绑定,它将在Pizza.objects.aggregate(topping_count=Count('toppings')) 中加入多个比萨,因此这个计数将返回超过浇头的总数。要获取与披萨相关的浇头总数(不重复计数),您可能需要执行Topping.objects.exclude(pizza_set=None).count() 之类的操作。
      猜你喜欢
      • 2010-10-01
      • 2011-11-22
      • 2011-09-25
      • 2011-07-12
      • 1970-01-01
      • 1970-01-01
      • 2011-02-12
      • 2010-11-02
      相关资源
      最近更新 更多