我正在尝试减少应用程序中的查询数量,并需要以下设置方面的帮助:
我有5个型号:
它们与以下内容相关联:
我的目标是找到与特定投注匹配的Spotprices。要做到这一点,我使用以下查询,但我确信它可以以更好的方式完成,所以当我进行100次投注并想要查看它们是否高于或低于相应的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 :(得分: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")
答案 1 :(得分:1)
在尝试减少查询数量之前,您应该对应用程序运行性能测试,并监视数据库负载。有时最好运行一些小查询而不是一个带有少量连接的大查询。某些版本的Oracle在加入时似乎特别糟糕。
联接的替代方法,如果您尝试避免n + 1查询问题,则使用preload
并传递关联(preload
采用与includes
相同的参数)。这使得ActiveRecord每个表运行一个查询。
基本上:
答案 2 :(得分:0)
这是一个非常简单的改变:
b = Bet.includes(:choice).find(5).choice
答案 3 :(得分:0)
经过几个小时和大量的Google搜索后,我找到了一个有效的解决方案..添加了我想要的连接桥后:
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
如果有人有更好的解决方案,请告诉我们:)