代码之家  ›  专栏  ›  技术社区  ›  Steve Ross

详细和摘要数据的ActiveRecord查询

  •  3
  • Steve Ross  · 技术社区  · 15 年前

    downloads 带 download_date 和 credits 柱。我要生成的是一个类似于:

     Date        Credits
     2010-11-01  25
     2010-11-01  27
    *2010-11-01  52  <= Sum of previous 2 rows
     2010-11-02  32
    *2010-11-02  32  <= Sum of previous row
    

    这可以通过以下方法实现:

    u.downloads.group_by(&:download_date).each do |date, downloads|
      downloads.each do |d|
        puts " %10s  %3d" % [d.download_date, d.credits]
      end
      puts "*%10s  %3d" % [date, downloads.sum(&:credits)]
    end
    

    这个解决方案虽然可以工作,但不像Rails那样,会导致发出大量的SQL查询。假设100个用户x 10000次下载/年,并且到年底为止,每服务一个页面的查询计数大约为1000000。

    如果可能的话,我提出的任何解决方案都应该是数据库不可知的。我知道我将在Heroku上使用PostgreSQL进行部署,而我的开发版本,尽管被误导了,仍然在MySQL上运行。

    我希望我已经提供了关于问题域和相关问题的足够信息。有什么意见或建议吗?

    2 回复  |  直到 15 年前
        1
  •  1
  •   Max Chernyak    15 年前

    你所做的实际上已经相当优化了。唯一的问题是一次只能下载一个。使用 u.downloads.all.group_by (添加 all

    更新: 尽管在第二个方面,在Rails 3中,这甚至不应该产生多个查询。你可能会遇到N+1问题的原因有很多。例如,如果您从视图中的某个相关对象返回引用某个特定的下载,rails可能不知道该下载已经作为数组的一部分从数据库中获取,然后再次重新获取。如果您看到许多查询,则此代码不应导致这些查询。

        2
  •  0
  •   Fábio Batista Raza Ahmed    15 年前

    u.downloads.group_by(&:download_date).each do |date, downloads|
      subtotal_credits = 0
      downloads.each do |d|
        puts " %10s  %3d" % [d.download_date, subtotal_credits += d.credits]
      end
      puts "*%10s  %3d" % [date, subtotal_credits]
    end