2016-09-24 2 views
0

私は3つのモデル、ポートフォリオ、株式とトランザクションがあります。私がポートフォリオ・ショー・ページにいるとき、私はポートフォリオの取引を繰り返し、私が購入したものを示すために株式をプロットします。JOINテーブルから株式を選択するときに、より良い方法をレールのクエリを行う

私は、ポートフォリオショーのページをロードすると、ログはこのようなものになります。showページ、Iループ内

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 

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) 

私の取引、株式やポートフォリオモデルは、これらの関連を持っているがインスタンスポートフォリオを介して、それはそれぞれの株式を取得するためにそれぞれの取引を使用しています。

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

ポートフォリオコントローラでは、@portfolioは@portfolio = Portfolio.find(params [:id])と定義されています。

関連するストックオブジェクトを取得するために、データベース(postgres)にクエリするより効率的な方法がありますか。今は問題ではありませんが、私は何年にもわたってポートフォリオを持ち、ポートフォリオ内で数百の取引をしていると考えています。または、私はmemcacheまたはredisを使用して、特定のポートフォリオページの結果をキャッシュすることを検討する必要がありますか?

答えて

0

これらのクエリを避けるには、関連付けを事前にロードする必要があります。このような
何か

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

これはN + 1 queries problemのように見える、あなたはそれを取り除くためにeager_loadまたはpreloadまたはincludesを使用することができます。

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

私は@portfolioオブジェクト再箔押し@portfolioへ= Portfolio.includes(:transactions、:stocks).find(params [:id])。 今、私はすべての在庫を1つのバッチで取得します。

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メソッドが劣化しているかどうかはわかりません。インクルードはもっと安定した選択のようです。

関連する問題