Sometimes people say that “fixing” some n+1 queries could hurt performance…
Maybe this phrase can be confusing, because if you have not been exposed to a lot of n+1 queries problems, it could be hard to imagine how it can be possible.
And also is probably contrary to what you have always heard…. That n+1 queries are bad.
Although a lot of the time a simple preload(:comments)
can solve your n+1
queries problems… sometimes it can also hurt the performance if you don’t put
attention in the queries that ActiveRecord is using.
Sometimes some of those queries will try to fetch a lot of data and that can make your queries slow or they can use to much memory and affect your application in general.
For example if you have a blog app with this model…
class Post < ApplicationRecord
has_many :comments
end
class Comment < ApplicationRecord
end
And you preload all the comments for each post…
posts = Post.preload(:comments)
If your posts, would normally have just a few comments, like 5 to 100 comments, everything will be fine….
But if your posts are very popular, and have between 5,000 and 10,000 maybe “just” preloading all the comments for each post could be a problem.
Maybe this example is not the most realistic example, but in general you need to be aware if the association that you want to preload could have a lot of records.
Other examples could be…
In a chat app:
messages
for all the channels
.reads
for the messages
on all the channels
.reactions
to the messages
.In an store or inventory system:
part_numbers
for a list of products
.page_views
for a list of products
.likes
for a list of products
.In a crowdfunding system:
investments
for all the projects
.payments
for all the investments
for all projects
.In general not all associations will be a problem, but be aware if your application have associations with too many records.
If your are in the situation where your fix was not really a fix or it is not good enough. Here are some things that you can try…
First, of all for a lot of this cases the first step is to implement a counter_cache.
And when you really need to preload the data because you need something more than a counter, you can give a look to:
Learn just enough fundamentals to be fluent preloading associations with ActiveRecord, and start helping your team to avoid n+1 queries on production.