35

我对急切加载和延迟加载感到困惑,rails 查询的性能有什么不同吗?

有没有办法实现这两种方式?

4

2 回答 2

53

急切加载

提高性能的一种方法是减少 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号。的用户朋友。

看看:Rails 3:延迟加载与急切加载

希望这能帮助您理解这一点。

于 2012-04-10T07:34:08.590 回答
20

渴望加载

临:是一切准备就绪。

缺点:您正在用完空间/内存。

延迟加载

一个轶事可能会帮助您记住:

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

于 2016-06-08T11:43:43.763 回答