I am confused about eager loading and lazy loading, is there any difference in the performance of rails queries?
Is there any way to implement both ways?
Eager Loading
One way to improve performance is to cut down on the number of SQL queries. You can do this through eager loading.
User.find(:all, :include => :friends)
Here you are firing only two queries :
1) One for all users.
2) One for all friends of users .
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.
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.
2) N query for N no. of users friends .
Take a look on : Rails 3: Lazy loading versus eager loading
Hope that will help you to understand this .
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.
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.
@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.name
in the view template - where product is a single object within the @products
relation. But if you alias it, you can get everything done with just one query:
@products = Product.order("categories.name").joins(:category).select("products.*, categories.name as category_name")
And use it like this: product.category_name