0

アプリケーションのクエリ数を減らしようとしていますが、次の設定でサポートが必要です。

私は5つのモデルを持っています:

  • ベット
  • 選択
  • スポット価格
  • スポットエリア
  • 製品

それらは以下に関連付けられています。

  • ベットbelongs_toChoice
  • 選択belongs_toSpotarea
  • 選択belongs_to製品
  • 選択has_manyベット
  • SpotpriceはSpotareaに属します
  • Spotpricebelongs_to製品
  • Spotarea has_many Spotprices
  • Spotarea has_many Choices
  • 製品has_manySprotprices
  • 製品has_manyChoices

私の目標は、特定の賭けに一致するスポット価格を見つけることです。これを行うには、次のクエリを使用しますが、より良い方法で実行できると確信しているため、100ベットを実行して、対応するSpotpriceを上回っているか下回っているかを確認したい場合は、DBをオーバーロードしません。クエリで。

a = Bet.find(5)

b = Choice.find(a.choice_id)

c = Spotprice.where(:spotarea_id => b.spotarea_id, :product_id => b.product_id, 
    :deliverydate => b.deliverydate).first

ありがとう!

4

4 に答える 4

1

まず、結合ブリッジを設定します。

class Choice
  has_many :spotprices, :through => :spotarea
end

class Bet
  has_many :spotprices, :through => :choice
end

次に、次のようなクエリを実行できます

Bet.joins(:spotprices).where("spotprices.price > bets.value")
于 2012-09-28T18:59:37.773 に答える
1

クエリの数を減らす前に、アプリでパフォーマンステストを実行し、データベースの負荷を監視する必要があります。いくつかの結合を持つ1つの大きなクエリよりも、いくつかの小さなクエリを実行する方がよい場合があります。Oracleの特定のバージョンは、結合が特に苦手なようです。

n + 1クエリの問題を回避しようとしている場合、結合の代わりにpreload、関連付けを使用して渡すこともできます(preloadと同じ引数を取りますincludes)。これにより、ActiveRecordはテーブルごとに1つのクエリを実行します。

基本的に:

  1. あなたは常にn+1の問題を避けたいのです。
  2. 複数のクエリを結合に結合しようとすると、最適化が時期尚早になる可能性があり、最悪の場合、実際にはパフォーマンスが低下します。
于 2012-09-28T19:51:53.357 に答える
0

さて、ここに1つの非常に簡単な変更があります:

b = Bet.includes(:choice).find(5).choice
于 2012-09-28T18:47:30.537 に答える
0

数時間と多くのグーグル検索の後、私はうまくいく解決策を見つけました。私がやりたかった結合ブリッジを追加した後:

Bet.find(5).spotprice

しかし、それを行うには、Choiceモデルに次のようなものが必要だったため、うまくいきませんでした。

has_one :spotprice, :through => [:spotarea, :product] :source => :spotprices

私はそれは不可能です..どうやら..

だから私はこのリンクhas_one:through => multipleを見つけ、私の状況でその答えを使うことができました。

class Choice < ActiveRecord::Base
  belongs_to :user
  belongs_to :spotarea
  belongs_to :product
  has_many   :bets

  def spotprice
    Spotprice.where(:product_id => self.product_id, :spotarea_id => self.spotarea_id, :deliverydate => self.deliverydate).first
  end

class Bet < ActiveRecord::Base
  belongs_to :user
  belongs_to :choice
  has_one    :spotprice, :through => :choice

上記で私は今することができます:

Bet.find(5).choice.spotprice

誰かがより良い解決策を手に入れたら私に知らせてください:)

于 2012-09-29T09:59:14.460 に答える