从JOIN表

时间:2016-09-24 16:23:53

标签: ruby-on-rails postgresql

我有3个模型,投资组合,股票和交易。当我在投资组合展示页面时,我会遍历投资组合的交易并绘制股票以显示我买的东西。

当我加载投资组合显示页面时,日志看起来像这样:

Started GET "/portfolios/1" for ::1 at 2016-09-24 02:15:32 -0400
Processing by PortfoliosController#show as HTML
  Parameters: {"id"=>"1"}
  Portfolio Load (0.6ms)  SELECT  "portfolios".* FROM "portfolios" 
 WHERE "portfolios"."id" = $1 LIMIT 1  [["id", 1]]
  Transaction Load (2.0ms)  SELECT "transactions".* FROM "transactions"
 WHERE "transactions"."portfolio_id" = $1  [["portfolio_id", 1]]
  Stock Load (1.7ms)  SELECT  "stocks".* FROM "stocks" WHERE "stocks"."id" = $1 LIMIT 1  [["id", 1]]
  Stock Load (0.2ms)  SELECT  "stocks".* FROM "stocks" WHERE "stocks"."id" = $1 LIMIT 1  [["id", 6]]
  Stock Load (0.2ms)  SELECT  "stocks".* FROM "stocks" WHERE "stocks"."id" = $1 LIMIT 1  [["id", 4]]
  CACHE (0.0ms)  SELECT  "stocks".* FROM "stocks" WHERE "stocks"."id" = $1 LIMIT 1  [["id", 6]]
  Stock Load (0.2ms)  SELECT  "stocks".* FROM "stocks" WHERE "stocks"."id" = $1 LIMIT 1  [["id", 2]]
  Stock Load (0.2ms)  SELECT  "stocks".* FROM "stocks" WHERE "stocks"."id" = $1 LIMIT 1  [["id", 13]]
  Stock Load (0.2ms)  SELECT  "stocks".* FROM "stocks" WHERE "stocks"."id" = $1 LIMIT 1  [["id", 9]]
  Stock Load (0.2ms)  SELECT  "stocks".* FROM "stocks" WHERE "stocks"."id" = $1 LIMIT 1  [["id", 16]]
  Stock Load (0.3ms)  SELECT "stocks".* FROM "stocks"
  Rendered transactions/_form.html.erb (19.1ms)
  Rendered portfolios/show.html.erb within layouts/application (69.6ms)
  Rendered application/_nav.html.erb (0.4ms)
Completed 200 OK in 128ms (Views: 90.5ms | ActiveRecord: 9.2ms)

我的交易,股票和投资组合模型都有这些关联:

class Transaction < ActiveRecord::Base
  belongs_to :portfolio
  belongs_to :stock
end

class Stock < ActiveRecord::Base
  has_many :transactions
end

class Portfolio < ActiveRecord::Base
  belongs_to :user
  has_many :transactions
  has_many :stocks, through: :transactions
end

在展示页面中,我循环浏览实例组合,并使用.each来获取相关股票。

<% @portfolio.transactions.each do |trade| %>

在投资组合控制器中,@ portfolio被定义为@portfolio = Portfolio.find(params [:id])。

是否有更有效的方法来查询数据库(postgres)以检索关联的库存对象。现在这不是一个问题,但我在考虑人们有多年的投资组合,并且在投资组合中有数百个交易。或者我应该考虑使用memcache或redis缓存特定投资组合页面的结果?

3 个答案:

答案 0 :(得分:0)

要避免这些查询,您需要预加载关联 像这样的东西

@portfolio = Portfolio.preload(:stocks).find(params[:id])

答案 1 :(得分:0)

这看起来像N + 1 queries problem,您可以使用Queueeager_loadpreload来摆脱它:

includes

答案 2 :(得分:0)

我将我的@portfolio对象重新编写为@portfolio = Portfolio.includes(:transactions,:stocks).find(params [:id])。 现在我一批获得所有股票。

  Parameters: {"id"=>"1"}
  Portfolio Load (0.3ms)  SELECT  "portfolios".* FROM "portfolios"
WHERE "portfolios"."id" = $1 LIMIT 1  [["id", 1]]
  Transaction Load (0.5ms)  SELECT "transactions".* FROM "transactions"
WHERE "transactions"."portfolio_id" IN (1)
  Stock Load (0.4ms)  SELECT "stocks".* FROM "stocks" WHERE
"stocks"."id" IN (1, 6, 4, 2, 13, 9, 16)
  Stock Load (0.3ms)  SELECT "stocks".* FROM "stocks"

这就是我想要的。由于我使用的是Rails 5,我不确定eager_load或preload方法是否会降级。包含似乎是一个更稳定的选择。