Ruby-on-rails Rails 中的预先加载和延迟加载

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10084355/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 03:12:17  来源:igfitidea点击:

eager loading and lazy loading in rails

ruby-on-railsruby-on-rails-3

提问by Arpit Vaishnav

I am confused about eager loading and lazy loading, is there any difference in the performance of rails queries?

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

Is there any way to implement both ways?

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

回答by Vik

Eager Loading

急切加载

One way to improve performance is to cut down on the number of SQL queries. You can do this through eager loading.

提高性能的一种方法是减少 SQL 查询的数量。您可以通过预先加载来做到这一点。

User.find(:all, :include => :friends)

Here you are firing only two queries :

在这里,您只触发两个查询:

1) One for all users.

1) 一个适用于所有用户。

2) One for all friends of users .

2)用户的所有朋友一个。

Lazy Loading:

延迟加载

When you have an object associated with many objects like a User has many Friends and you want to display a list as in Orkut you fire as many queries as there are friends, plus one for the object itself.

当您有一个对象与许多对象相关联时,例如用户有很多朋友,并且您想在 Orkut 中显示一个列表,您可以触发与朋友一样多的查询,再加上一个对象本身。

users = User.find(:all)

Then query for each user friend , like :

然后查询每个用户朋友,例如:

users.each do |user|
  friend = Friend.find_by_user_id(user.id)
end

Here

这里

1) One query for all users.

1) 一个查询所有用户。

2) N query for N no. of users friends .

2) N 查询 N 号。的网友朋友。

Take a look on : Rails 3: Lazy loading versus eager loading

看一看:Rails 3:延迟加载与预先加载

Hope that will help you to understand this .

希望这会帮助你理解这一点。

回答by BKSpurgeon

Eager loading

急切加载

Loads your guns (like in Vicksburg) and just wait till you actually need to use it. This is a policy of eager loading.

装上你的枪(就像在维克斯堡一样),然后等到你真正需要使用它。这是一种急切加载的策略。

Pro: is that everything's ready to go.

亲:一切都准备好了。

Con: you are using up space/memory.

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

Lazy Loading

延迟加载

A young naval cadet asked Lord Nelson why he wasn't preparing his ships:

一位年轻的海军学员问纳尔逊勋爵为什么不准备他的船只:

"I won't load my guns early.......I'll load just 1 microsecond before I need to fire it." he said. This is a lazy loading policy.

“我不会提前装弹……我会在需要开火前 1 微秒装弹。” 他说。这是一个延迟加载策略。

Pro of lazy loading: you don't hit the database until you need to.

延迟加载的优点:除非需要,否则不会访问数据库。

Con: You'll be hitting the database N + 1 times.....unless you select exactly the column you want and you alias it. e.g.

缺点:您将访问数据库 N + 1 次.....除非您准确选择所需的列并为其设置别名。例如

@products = Product.order("categories.name").joins(:category)

Hitting the Database only once with a lazy loading policy:

使用延迟加载策略仅命中数据库一次:

The above query hits the database N + 1 times when you call product.category.namein the view template - where product is a single object within the @productsrelation. But if you alias it, you can get everything done with just one query:

当您product.category.name在视图模板中调用时,上述查询命中数据库 N + 1 次- 其中 product 是@products关系中的单个对象。但是如果你给它取别名,你只需一个查询就可以完成所有事情:

@products = Product.order("categories.name").joins(:category).select("products.*, categories.name as category_name")

And use it like this: product.category_name

并像这样使用它:product.category_name