Do you struggle fixing N+1 queries because is hard for you to detect why ActiveRecord seems to ignore your “includes”?
Wouldn’t it be nice to just see some piece of code and know when the query will execute?
Well… this exercise will try to help you achieve this… to help you identify when a query will execute by just watching the code :)
I will show you 10 code examples using ActiveRecord’s query interface, like includes
, order
and where
.
For each code example you will:
If you are just starting, the excercises could be hard!… Don’t worry, that’s expected, with practice it will be easier!
Post.includes(:comments).to_a
Answer
to_a
Post.includes(:comments).order(:id).to_a
Answer
to_a
Post.all.each do |post|
post.comments
post.sorted_comments.to_a
end
Answer
each
on Post.all.each
to_a
on post.sorted_comments
Post.includes(:comments).each do |post|
post.comments.to_a
end
Answer
each
on Post.includes(:comments).each
Post.includes(:comments).each do |post|
post.comments.order(:id)
post.comments.order(:id).to_a
end
Answer
each
on Post.includes(:comments).each
to_a
on post.comments.order(:id).to_a
Post.includes(:sorted_comments).each do |post|
post.sorted_comments.to_a
post.comments.to_a
end
Answer
each
on Post.includes(:sorted_comments).each
to_a
on post.comments.to_a
Post.includes(:sorted_comments).each do |post|
post.sorted_comments.first
post.comments.first
end
Answer
each
on Post.includes(:sorted_comments).each
first
on post.comments.first
Post.includes(:sorted_comments).map do |post|
post.sorted_comments.last
post.comments.last
end
Answer
map
on Post.includes(:sorted_comments).map
last
on post.comments.last
Post.includes(:sorted_comments).sort_by(&:id).each do |post|
post.sorted_comments.limit(1).first
post.comments.to_a.limit(1).first
end
Answer
sort_by
on Post.includes(:sorted_comments).sort_by(&:id).each
first
on post.sorted_comments.limit(1).first
first
on post.comments.to_a.limit(1)
Post.includes(:comments).where("comments.points > 5").references(:comments).each do |post|
post.comments.to_a
post.comments.order(:id).to_a
post.comments.sort_by(&:id).to_a
end
Answer
each
on Post.includes(:comments).where("comments.points > 5").references(:comments).each
to_a
on post.comments.order(:id).to_a
Been able to identify when a query will execute, just by watching the code is an ability that will make you job, much more easy.
Maybe at the beginning it will be hard, but the more you practice the easier that it will be.
So if you already can answer all the excercises right, try to create your own excercises and practice until you feel confident of your ability.
Other thing that you could do is to actually run the code of each excercise and also experiment changing them to try to understand what’s happening. You can find the code on bhserna/when the query is executed
Learn just enough fundamentals to be fluent preloading associations with ActiveRecord, and start helping your team to avoid n+1 queries on production.