【发布时间】:2012-04-10 06:53:45
【问题描述】:
我对渴望加载和延迟加载感到困惑,rails查询的性能有什么区别吗?
有没有办法实现这两种方式?
【问题讨论】:
标签: ruby-on-rails ruby-on-rails-3
我对渴望加载和延迟加载感到困惑,rails查询的性能有什么区别吗?
有没有办法实现这两种方式?
【问题讨论】:
标签: ruby-on-rails ruby-on-rails-3
提高性能的一种方法是减少 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: Lazy loading versus eager loading
希望能帮助你理解这一点。
【讨论】:
"Lazy loading is a design pattern commonly used in computer programming to defer initialization of an object until the point at which it is needed. It can contribute to efficiency in the program's operation if properly and appropriately used." -Wikipedia 基本上,如果您的页面有一堆用户在滚动之前看不到的图像,您可以等到他向下滚动并看到图像来加载它。那是延迟加载。
预加载
专业人士:一切准备就绪。
Con:你正在用完空间/内存。
延迟加载
一个轶事可能会帮助你记住:
A young naval cadet asked Lord Nelson why he wasn't preparing his ships:
“我不会提前装弹……我会在 1 微秒前装弹 我需要开火。”他说。“我很懒惰。我更喜欢在 最后一分钟,就像我的大学作业等一样。”
延迟加载的优点:直到需要时才访问数据库。
Con:您将访问数据库 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
【讨论】: