【问题标题】:Performance improvement for Rails associated model aggregationRails 相关模型聚合的性能改进
【发布时间】:2012-12-18 05:17:25
【问题描述】:

我有一个名为 Person 的模型,而 Person 有多个帖子。当我想查询每个人的帖子计数时,它需要很长时间来处理,因为它需要遍历每个人并查询每个帖子以获取聚合。

class Person < ActiveRecord::Base
has_many :posts
end

输出 (JSON):

Person1
  PostsType1Count: 15
  PostsType2Count: 45
Person2
  PostsType3Count: 33
.
.
.

我想以最佳方式计算每个人的所有帖子数。最好的解决方案是什么?

【问题讨论】:

  • 为什么一个人有多个帖子数?
  • 有不同类型的帖子。我需要单独计算它们
  • 如果您的帖子类型是预定义的,请在 Person 上为每种类型的帖子添加一列,并预先加载该工作。发布帖子后,增加适当的计数,然后更新计数是微不足道的。

标签: mysql ruby-on-rails performance


【解决方案1】:

如果您有一组小的预定义类型,这是一种方法

class Person < ActiveRecord::Base
  has_many :type_1_posts, :class_name => 'Post', :conditions => 'post_type = 1'
  has_many :type_2_posts, :class_name => 'Post', :conditions => 'post_type = 2'
  has_many :type_3_posts, :class_name => 'Post', :conditions => 'post_type = 3'
end

然后你可以编写如下代码来获取所有数据:

@all_people = Person.includes(:type_1_posts, :type_2_posts, :type_3_posts).all

帖子的热切加载允许提供每种类型帖子的计数,以及每种类型的所有帖子。

如果您需要此代码的额外性能,因为您经常执行此查询,那么您可以考虑使用 Rails counter cache 机制来跟踪 Person 上每种类型的计数对象。

Rails 的美妙之处在于,您的主要显示代码在此过程中无需更改,从而加快代码阅读速度(添加计数器缓存会使添加/删除帖子变慢,因此您可能根本不想要它例)。

  1. 编写初始代码
  2. 使用即时加载使其更快
  3. 使用计数器缓存使其更快

【讨论】:

    【解决方案2】:

    试试这个五月它会为你工作

        #In Controller
        @persons = Person.all
        #In View
        @persons.each do |person|
             person.posts.count # It will gives all posts count
             person.posts.collect{|x| true if x.type==1 }.compact.count #If you want to get the post counts based on type
        end
    

    假设如果您想获得任何方法,只需检查控制台或调试是 person.methods.sort 它将提供所有方法。
    尝试在 rails 控制台 person.posts.methods 也会给出类型,然后根据类型检查计数。因为我不知道帖子模型中有哪些字段。所以检查一下。

    【讨论】:

    • 我在使用上述方法时面临的问题是,我们需要对人员进行迭代,并在每次迭代中获取帖子数,这在性能上是代价高昂的。我正在寻找一种可以进行计数的方法(可能在数据库查询本身并给出结果或更优化的方法)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-08
    • 2017-04-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多