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:
messagesfor all the
messageson all the
In an store or inventory system:
part_numbersfor a list of
page_viewsfor a list of
likesfor a list of
In a crowdfunding system:
investmentsfor all the
paymentsfor all the
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: