2012-09-28 17 views
0

我想減少我的應用程序查詢的數量和需要一些幫助,下面的設置:簡化Rails的查詢

我有5款車型:

  • 投注
  • 選擇
  • Spotprice
  • Spotarea
  • 產品

它們與以下有關:

  • 投注belongs_to的選擇
  • 選擇belongs_to的Spotarea
  • 選擇belongs_to的產品
  • 選擇的has_many投注
  • Spotprice belongs_to的Spotarea
  • Spotprice belongs_to的產品
  • Spotarea has_many Spotprices
  • Spotarea的has_many選擇
  • 產品的has_many Sprotprices
  • 產品的has_many選擇

我的目標是找到匹配的BET比的Spotprices。要做到這一點,我使用了以下查詢,但我相信它可以以更好的方式完成,所以當我通過100次投注並想要查看它們是否高於或低於corrosponding Spotprice時,我不會超載數據庫與查詢。

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 

謝謝!

回答

0

了幾個小時,大量的谷歌搜索後,我發現一個可行的解決方案..加入加盟橋之後,我想做的事:

Bet.find(5).spotprice 

但是,這並不能工作,因爲做我需要這樣的事情在我的選擇模型:

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

我這是不可能的.. apperently ..

所以我發現這個鏈接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 

如果有人得到了一個更好的解決方案,請讓我知道:)

0

那麼這裏是一個很簡單的變化:

b = Bet.includes(:choice).find(5).choice 
+0

:包括做一個單獨的查詢和紅寶石連接。使用:連接來實現真正的連接 – rewritten

+0

這並非完全正確。它有時會做一個額外的查詢,有時不會。 – weexpectedTHIS

1

首先,建立加盟橋樑:像

Bet.joins(:spotprices).where("spotprices.price > bets.value") 
+0

謝謝..連接橋肯定有幫助,但仍然沒有完全解決這個問題..我已經發布瞭解決方案的答案..感謝您的幫助引導我在正確的方向.. – Twiddr

1

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

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

然後你就可以查詢的東西試圖之前減少查詢次數,您應該對您的應用運行性能測試,並監視數據庫負載。有時候最好是運行一些小的查詢,而不是一個帶有幾個連接的巨大查詢。某些版本的Oracle在連接上顯得尤爲糟糕。

的替代連接,如果你想避免N + 1個查詢的問題,就是用preload並通過協會(preload採用相同的參數includes)。這使得ActiveRecord爲每個表運行一個查詢。

基本上是:

  1. 你總是想避免N + 1點的問題。
  2. 試圖將多個查詢合併到一個連接中可能會導致過早優化,並且在最壞的情況下實際上會使性能變差。
+0

謝謝你的偉大答案..我一定會研究'preload'的東西,並儘量避免n + 1的問題..我不得不查找的原因,我不知道你的補習:) – Twiddr