Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 4 Eager Load has_many Associations for single object

I get the benefits of using eager loading to avoid N+1 when fetching an array of objects with their associated records, but is it important to use eager loading when fetching a single record?

In my case

user has_many :addresses
user has_many :skills
user has_many :devices
user has_many :authentications

In the show action, I am trying to see with rack mini profiler if it is interesting to use eager loading

User.includes(:skills, :addresses, :devices, :authentications).find(params[:id])

But I seem to have the same number of sql requests..

Any advice on using eager loading for such case or not?

like image 432
stefano_cdn Avatar asked Dec 09 '22 00:12

stefano_cdn


1 Answers

is it important to use eager loading when fetching a single record?

For associations one level deep, no.

If you have nested associations, yes.

# class User
has_many :skills

# class Skill
belongs_to :category

# this code will fire N + 1 queries for skill->category
user.skills.each do |skill|
  puts skill.category
end

In this case, it is better to eager load skills: :category

User.includes(skills: :category).find(id)

Edit

Rails provide two ways to avoid N+1 queries, which it refers to as preloading and eager_loading.

Preload fires individual SQL queries for each collection.

Eager load attempts to construct one massive left-joined SELECT to retrieve all collections in 1 query.

The short version is that includes lets Rails pick which one to use. But you can force one way or the other.

User.eager_load(:skills, :addresses, :devices, :authentications).find(params[:id])

Should retrieve all records in 1 query.

Further reading:

  • What's the difference between “includes” and “preload” in an ActiveRecord query?
  • http://blog.bigbinary.com/2013/07/01/preload-vs-eager-load-vs-joins-vs-includes.html
  • http://blog.arkency.com/2013/12/rails4-preloading/
like image 65
messanjah Avatar answered Jan 26 '23 00:01

messanjah