你们如何提前检索代码中的所有对象?
如果将所有模型调用捆绑在一起,我认为可以提高性能?
这会产生更大的交易,特别是如果你的数据库无法将所有内容保存在内存中
def hitDBSeperately {
获取X用户 ...代码
获取Y个用户...代码
获取Z用户...代码
}
Versus:
def hitDBInSingleCall {
获取X + Y + Z用户
X的代码 代码为Y ...
}
答案 0 :(得分:1)
您是否正在寻找一次性加载所有用户的方法之间的解释:
# Loads all users into memory simultaneously
@users = User.all
@users.each do |user|
# ...
end
您可以在哪里单独加载它们以减少内存占用量?
@user_ids = User.connection.select_values("SELECT id FROM users")
@user_ids.each do |user_id|
user = User.find(user_id)
# ...
end
第二种方法会慢一些,因为它需要为N个用户提供N + 1个查询,其中第一个用一个查询加载它们。但是,您需要有足够的内存来同时为每个用户记录创建模型实例。这不是“DB memory”的功能,而是应用程序内存的功能。
对于具有非平凡数量的用户的任何应用程序,您应该使用单独或成组加载用户的方法。您可以使用以下方式执行此操作:
@user_ids.in_groups_of(10) do |user_ids|
User.find_all_by_id(user_ids).each do |user|
# ...
end
end
通过调整以使用适当的分组因子,您可以在内存使用和性能之间取得平衡。
答案 1 :(得分:1)
你能在rails代码上给出一些实际的ruby,我们的伪代码有点令人困惑吗?
您可以使用预先加载来避免n + 1问题。您可以使用:includes =>完成此操作您的model.find方法中的标记。
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html