查询性能比较

时间:2020-08-29 16:38:33

标签: ruby-on-rails

我正在制作instagram复制副本。我想进行一次查询,以获取所有喜欢该帖子的用户。总而言之,一个用户有很多帖子,一个帖子有很多喜欢,并且用户也有很多喜欢。这些是我想出的解决方案

def get_user_likes
    post = Post.find(params[:post_id])
    #first solution
    @user_likes =  post.likes.map(&:users)
    #second solution
    @user_likes = User.includes(:likes).select(:username, :id, :profile_image).where(
        likes: {post_id: params[:post_id])})
end

我也只想选择几列(第一个选项不允许我)。在性能方面,哪个选项更好?有更好的选择吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

就像Mehmet所说的那样,第二种解决方案更好。 我将扩展一下注释,第一个解决方案很容易理解,但是会针对地图中的每个类似对象调用一个查询,这些问题通常称为n + 1查询。

第二种解决方案更好,但是并不是您想要的。包含将运行第二个查询,并且以后可以迭代对象。

最好的解决方案是使用联接,首先是因为它将减少一个查询,其次是因为它将完全返回您的查询,因此只需将您的包含替换为联接,就可以了:

def user_likes
  @user_likes = User.joins(:likes).select(:username, :id, :profile_image).where(likes: {post_id: params[:post_id])})
end

我可以进行更多探索,但答案将是博客文章,我可以为您推荐博客文章: https://semaphoreci.com/blog/2017/08/09/faster-rails-eliminating-n-plus-one-queries.html