我正在使用Ruby on Rails 3.0.7,我正在努力减少数据库命中。为此,我从数据库中检索与Article
相关的所有User
个对象,然后对这些检索到的对象执行搜索。
我的工作是:
stored_objects = Article.where(:user_id => <id>) # => ActiveRecord::Relation
<some_iterative_function_1>.each { |...|
stored_object = stored_objects.where(:status => 'published').limit(1)
...
# perform operation on the current 'stored_object' considered
}
<some_iterative_function_2>.each { |...|
stored_object = stored_objects.where(:visibility => 'public').limit(1)
...
# perform operation on the current 'stored_object' considered
}
<some_iterative_function_n>.each { |...|
...
}
stored_object = stored_objects.where(:status => 'published')
代码真的会避免命中数据库(我问这个,因为在我的日志文件中它的接缝仍然运行each
迭代的数据库查询)?如果不是,我怎样才能最大限度地减少数据库命中?
ActiveRecord::Relation
(一个数组),但调用它的where
方法接缝到数据库。
答案 0 :(得分:1)
一旦你开始迭代stored_objects
(如果你正在做的那样),它们将从数据库加载。如果您只想加载用户发布的文章,可以这样做:
stored_objects = Article.where(:user_id => id, :status => 'published')
如果您想要加载已发布的和未发布的文章,并针对已发布的文章执行不同的操作,则可以执行以下操作:
stored_objects = Article.where(:user_id => id)
stored_objects.find_all { |a| a.status == 'published' }. each do |a|
# ... do something with a published article
end
或者也许:
Article.where(:user_id => id).each do |article|
case article.status
when 'published'
# ... do something with a published article
else
# ... do something with an article that's not published
end
end
这些示例中的每一个仅执行一次数据库查询。选择哪一个取决于您真正想要使用哪些数据。
答案 1 :(得分:1)
Rails具有一次抓取数据库块的功能,然后迭代遍历行,而不必再次访问数据库。
有关find_each
和find_in_batches
的详情,请参阅“Retrieving Multiple Objects in Batches”。