Rails too many queries?
Just doing some Rails and noticed that when displaying 30 products on a single page using @products.each do
it appears as though there are a lot of queries going on in the background, see below for my console output. Is this right or am I reading this entirely wrong?
Category Load (0.1ms) SELECT "categories".* FROM "categories" WHERE ("categories"."name" = 'bras') LIMIT 1
Product Load (28.0ms) SELECT "products".* FROM "products" WHERE ("products".category_id = 48)
Brand Load (0.2ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
Category Load (0.1ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
Merchant Load (0.1ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (16.9ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.8ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.5ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.5ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.5ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.5ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.5ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.5ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.7ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.4ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.5ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.4ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.5ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.5ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.6ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.5ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.5ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.5ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.5ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.6ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.4ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.5ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.5ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (2.0ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.4ms)
CACHE (开发者_JAVA百科0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.5ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.5ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.6ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Rendered products/_product.html.erb (1.5ms)
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Update: Sorry I am specifically talking about the CACHE lines, do these mean these queries are not run everytime?
CACHE (0.0ms) SELECT "brands".* FROM "brands" WHERE ("brands"."id" = 408) LIMIT 1
CACHE (0.0ms) SELECT "categories".* FROM "categories" WHERE ("categories"."id" = 48) LIMIT 1
CACHE (0.0ms) SELECT "merchants".* FROM "merchants" WHERE ("merchants"."id" = 2) LIMIT 1
Here is the code from the product partial:
<h3><%= product.product_name %></h3>
<img src="<%= product.image %>" align="right" alt="<%= product.product_name %>" height="200" />
<p><%= truncate(product.product_description, :length => 300, :omission => "...") %></p>
<p><%= product.price %></p>
<p>Brand: <%= product.brand.brand_name %></p>
<p>Category: <%= product.category.category_name %></p>
<p>Merchant: <%= product.merchant.merchant_name %></p>
<p><a href="<%= product.link %>" target="_blank">More information</a></p>
<hr />
You might want to eager load your products/merchants/etc
@product = Product.find(conditions, :include => {:category, :brand, :merchant})
(I don't know your relations so use as needed)
EDIT in regards to your cache question, no those queries aren't run against the server, but you should definitely look into eager loading so you don't have unnecessary querying going on
For more details see the following
http://rails-bestpractices.com/posts/29-fix-n-1-queries
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html <- See Eager loading
Those CACHEd queries are only run once but you still want to join them in initially. In your controller, you will want to do @products = Product.all(:include => [:brand, :category, :merchant])
Also, it is a little bit expensive to repeatedly render a small partial. I have had better luck making the partials themselves loop over the collection:
products/_products.html.erb
<% products.each do |product| %>
<h3><%= product.product_name %></h3>
<img src="<%= product.image %>" align="right" alt="<%= product.product_name %>" height="200" />
<p><%= truncate(product.product_description, :length => 300, :omission => "...") %></p>
<p><%= product.price %></p>
<p>Brand: <%= product.brand.brand_name %></p>
<p>Category: <%= product.category.category_name %></p>
<p>Merchant: <%= product.merchant.merchant_name %></p>
<p><a href="<%= product.link %>" target="_blank">More information</a></p>
<hr />
<% end %>
精彩评论