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
to_aPost.includes(:comments).order(:id).to_a
to_aPost.all.each do |post|
post.comments
post.sorted_comments.to_a
end
each on Post.all.eachto_a on post.sorted_commentsPost.includes(:comments).each do |post|
post.comments.to_a
end
each on Post.includes(:comments).eachPost.includes(:comments).each do |post|
post.comments.order(:id)
post.comments.order(:id).to_a
end
each on Post.includes(:comments).eachto_a on post.comments.order(:id).to_aPost.includes(:sorted_comments).each do |post|
post.sorted_comments.to_a
post.comments.to_a
end
each on Post.includes(:sorted_comments).eachto_a on post.comments.to_aPost.includes(:sorted_comments).each do |post|
post.sorted_comments.first
post.comments.first
end
each on Post.includes(:sorted_comments).eachfirst on post.comments.firstPost.includes(:sorted_comments).map do |post|
post.sorted_comments.last
post.comments.last
end
map on Post.includes(:sorted_comments).maplast on post.comments.lastPost.includes(:sorted_comments).sort_by(&:id).each do |post|
post.sorted_comments.limit(1).first
post.comments.to_a.limit(1).first
end
sort_by on Post.includes(:sorted_comments).sort_by(&:id).eachfirst on post.sorted_comments.limit(1).firstfirst 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
each on Post.includes(:comments).where("comments.points > 5").references(:comments).eachto_a on post.comments.order(:id).to_aBeen 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.