我对急切加载和延迟加载感到困惑,rails 查询的性能有什么不同吗?
有没有办法实现这两种方式?
提高性能的一种方法是减少 SQL 查询的数量。您可以通过预先加载来做到这一点。
User.find(:all, :include => :friends)
在这里,您只触发了两个查询:
1) 一个适用于所有用户。
2) 一个给所有用户的朋友。
延迟加载:
当您有一个与许多对象相关联的对象时,例如用户有很多朋友,并且您希望像在 Orkut 中一样显示一个列表,您会触发与朋友一样多的查询,再加上一个针对对象本身的查询。
users = User.find(:all)
然后查询每个用户朋友,例如:
users.each do |user|
friend = Friend.find_by_user_id(user.id)
end
这里
1) 一次查询所有用户。
2)N查询N号。的用户朋友。
希望这能帮助您理解这一点。
渴望加载
临:是一切准备就绪。
缺点:您正在用完空间/内存。
延迟加载
一个轶事可能会帮助您记住:
A young naval cadet asked Lord Nelson why he wasn't preparing his ships:
“我不会提前装弹……我会在需要开火前 1 微秒装弹。” 他说。“我很懒惰。我更喜欢在最后一刻才这样做,就像我的大学作业等一样。”
延迟加载的优点:除非需要,否则不会访问数据库。
缺点:您将访问数据库 N + 1 次.....除非您准确选择所需的列并为其设置别名。例如
@products = Product.order("categories.name").joins(:category)
使用延迟加载策略仅访问数据库一次:
当您product.category.name
在视图模板中调用时,上述查询会命中数据库 N + 1 次 - 其中 product 是关系中的单个对象@products
。但是如果你给它起别名,你可以通过一个查询来完成所有的事情:
@products = Product.order("categories.name").joins(:category).select("products.*, categories.name as category_name")
并像这样使用它:product.category_name