Eager loading and Lazy loading in Rails ActiveRecord

Eager loading loads the full objects tree that is the associated records of the objects.

Consider we have two models Post and Comment and we have relation like post has many comments.

Post model has the relation has_many :comments
Comment model has the relation belongs_to :post

Now lets find all the posts and its comments and print the post text and comment text.

posts = Post.all(:limit => 20)

Next we will iterate through all the post and and then get the comments for that post and print the post and comment text.

posts.each do |post|
puts post.post_text
 post.comments.each do | comment |
  puts comment.comment_text
 end
end

Okay this code works fine, nothing wrong but there is performance issue in this code, it fires 1 query to find all the post and N queries to find the comments for the post.

Lets try to measure the time taken to execute this code using Ruby Benchmark.

require 'benchmark'

lazy loading = Benchmark.measure do
posts = Post.all(:limit => 20)
posts.each do |post| 
puts post.post_text
 post.comments.each do | comment |
  puts comment
 end
end
end.total
puts lazy loading #

Lets try to optimize the performance by trying some ways.
We can use the includes method provided by Active Record that loads the full objects tree that is the associated records of the objects.

posts = Post.includes(:comments).limit(20)
posts.each do |post|
puts post.post_text
 post.comments.each do | comment |
  puts comment.comment_text
 end
end

The above code fire 2 queries, one to find all the posts and the other to find the comments for the posts.
This concept is called eager loading, so the posts variable contains all the posts and the associated comments.

Lets try to measure the time taken to execute this code using Ruby Benchmark.

require 'benchmark'
eager_loading = Benchmark.measure do
posts = Post.includes(:comments).limit(20)
posts.each do  |post|
puts post.post_text
 post.comments.each do | comment |
  puts comment.comment_text
 end
end
end.total
puts eager_loading #

The time taken in eager loading is very less compared to lazy loading, so it is good to go with eager loading when we show associations data.

pixelstats trackingpixel

1 Comment. Leave new

Multi-threaded use of Rails ActiveRecord 3.0-3.1 | Bibliographic Wilderness
November 15, 2011 1:01 AM

[...] block? Maybe you just missed a place, but this is also very easy to do because of the way ActiveRecord lazily loads association content and does other kinds of database access “on [...]

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>