Reputation: 215
I have the following model structure:
class Group < ActiveRecord::Base
has_many :group_products, :dependent => :destroy
has_many :products, :through => :group_products
end
class Product < ActiveRecord::Base
has_many :group_products, :dependent => :destroy
has_many :groups, :through => :group_products
end
class GroupProduct < ActiveRecord::Base
belongs_to :group
belongs_to :product
end
I wanted to minimize my database queries so I decided to use includes.In the console I tried something like,
groups = Group.includes(:products)
my development logs show the following calls,
Group Load (403.0ms) SELECT `groups`.* FROM `groups`
GroupProduct Load (60.0ms) SELECT `group_products`.* FROM `group_products` WHERE (`group_products`.group_id IN (1,3,14,15,16,18,19,20,21,22,23,24,25,26,27,28,29,30,33,42,49,51))
Product Load (22.0ms) SELECT `products`.* FROM `products` WHERE (`products`.`id` IN (382,304,353,12,63,103,104,105,262,377,263,264,265,283,284,285,286,287,302,306,307,308,328,335,336,337,340,355,59,60,61,247,309,311,66,30,274,294,324,350,140,176,177,178,64,240,327,332,338,380,383,252,254,255,256,257,325,326))
Product Load (10.0ms) SELECT `products`.* FROM `products` WHERE (`products`.`id` = 377) LIMIT 1
I could analyze the initial three calls were necessary but don't get the reason why the last database call is made,
Product Load (10.0ms) SELECT `products`.* FROM `products` WHERE (`products`.`id` = 377) LIMIT 1
Any idea why this is happening? Thanks in advance. :)
Upvotes: 3
Views: 1413
Reputation: 2759
Now you can easily find N+1 query call using bullet gem (help to kill N+1 queries and unused eager loading.)
Use this gem it will tell you where you need to work around to kill N+1 call and also tell if somewhere eager loading not requires.
It helps me lot use this and then try it out, you will get solution of your problem.
Read below article explain you more about different ways to perform eager loading -
3 ways to do eager loading (preloading) in Rails 3 & 4
Upvotes: -1
Reputation: 21
I was having a similar issue when issuing a where()
call. The problem was due to some "lazy evaluation" being done for ActiveRecords::Relation
(as sailor mentioned above). The solution is to simply add a .to_a
at the end of the call. It should work for your includes()
statement above too. For more info, see:
http://daveinabottle.schweisguth.org/2011/05/01/avoiding-extra-queries-in-activerecord-3/
Upvotes: 2
Reputation: 11710
I don't think that fourth query is coming from this line of code (or the collection created by it). Even if you did something like groups.products.find(product_id)
somewhere later, you would see a much more complex query, with the inner joins on the join table. It looks like there must be a separate Product.find(product_id)
or something similar somewhere in your code.
Upvotes: 0