如果我有很多用户,帖子,喜欢,如何组织查询到数据库

时间:2012-09-10 16:54:49

标签: mysql ruby-on-rails ruby activerecord

我有一个用户,关系,帖子,喜欢的应用程序 我的模特是:

class User
  has_many :posts
  has_many :likes
  has_many :relationships, :foreign_key => "follower_id", :dependent => :destroy
end

class Post
  belongs_to :user
  has_many :likes  
end

class Like
  belongs_to :user
  belongs_to :post
end

class Relationship
  belongs_to :follower, :class_name => "User"
  belongs_to :followed, :class_name => "User"
end

所以我想找到至少100位喜欢我当前帖子的用户:

friends = User.find(user.followers).likes.where(:post => @post, :limit => 100)

如果DB中有很多用户,帖子,喜欢等,这是一个简单但不优化的查询 如何优化查询(或模型)以提高速度并减少查询的执行时间?

3 个答案:

答案 0 :(得分:1)

嗯,首先要做的是确保所有表格都有适当的索引。

因此,应该有用于连接表的所有主键和外键的索引。当然,您希望在这些表中可能用于排序或过滤的任何字段上建立索引。

除此之外,我没有发现您的数据库架构有任何问题。

但是,如果您想查看非关系型数据库,很多开发人员都会使用NoSQL存储来解决这些问题,例如这些问题,你有一个主帖,但可能有任意数量的喜欢,评论等等。 。在JSON中维护单个NoSQL文档条目非常容易,它包含单个帖子的整个树结构,而不必在关系数据库结构中从不同的表中组装此信息。

答案 1 :(得分:0)

我同意迈克的观点。您的架构看起来不错,但您应该添加一些索引。

如果您遇到性能问题,最好的选择是对某些数据进行非规范化(即预先计算一些查询并缓存结果)。

明显的缓存候选者将为特定用户或帖子存储“喜欢”计数。每次有人点击“赞”时你都可以更新,或者你只能偶尔通过一个cron工作或类似的东西来更新计数。然后你就可以在没有实际运行JOIN查询的情况下快速报告“这样的234个人”。如果你有时只重新计算它,那么存储的计数可能会失去同步,但这对于这个应用来说并不是什么大不了的事(它不像是银行账户余额!)。

答案 2 :(得分:0)

拥有索引并尝试使用预先加载。像

这样的东西
users = User.includes(:likes => [:post]).find(user.followers)
friends = users.where(:post => @post).limit(100)

当您有大量数据时,使用find_in_batches将节省内存消耗,因为每个批处理事务将释放Activerecord内存