【问题标题】:How to retrieve both "associated" records and "associated through" records in a performant way?如何以高效的方式检索“关联”记录和“关联通过”记录?
【发布时间】:2012-03-04 15:40:14
【问题描述】:

我正在使用 Ruby on Rails 3.1,并且我正在尝试改进 SQL 查询,以便以高效的方式检索“关联”记录和“关联通过”记录 (ActiveRecord::Associations),以避免“N + 1 查询问题”。也就是说,我有:

class Article < ActiveRecord::Base
  has_many :category_relationships

  has_many :categories,
    :through => :category_relationships
end

class Category < ActiveRecord::Base
  has_many :article_relationships

  has_many :articles,
    :through => :article_relationships
end

在几个 SQL 查询中(即以“高性能方式”,可能使用 Ruby on Rails includes() 方法)我想同时检索 categoriescategory_relationships em>,articlesarticle_relationships

我怎样才能做到这一点?


P.S.:我正在改进如下查询:

@category = Category.first

articles = @category.articles.where(:user_id => @current_user.id)
articles.each do |article|
  # Note: In this example the 'inspect' method is just a method to "trigger" the
  # "eager loading" functionalities
  article.category_relationships.inspect
end

【问题讨论】:

  • 你到底要优化什么查询?
  • @iltempo - 我更新了问题。

标签: sql ruby-on-rails ruby ruby-on-rails-3 performance


【解决方案1】:

你可以的

Article.includes(:category_relationships => :categories).find(1)

这将减少到 3 个查询(每个表 1 个)。为了提高性能,还要确保您的外键具有索引。

但总的来说,我很好奇为什么“category_relationships”实体存在,为什么这不是has_and_belongs_to这种情况?

更新

根据您更改的问题,您仍然可以这样做

Category.includes(:article_relationships => :articles).first

如果您查看控制台(或尾部日志/开发),您会发现当您调用关联时,它会命中缓存值,您就可以了。

但我仍然很好奇您为什么不使用 Has and Belongs To Many 关联。

【讨论】:

  • 如果我使用一些语句,包括where 方法,例如:Article.includes(:category_relationships =&gt; :categories).where(:user_id =&gt; 1)?我得到相同的结果(关于性能)? 顺便说一句includes() 到底是如何工作的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-21
  • 1970-01-01
相关资源
最近更新 更多