我目前有这样的模型设置( - > =一对多):
Trader-> Service-> ServiceLocation< -Locations-> Trader(如果有意义的话)
交易者有一个原始位置,一个服务有一个范围,每次保存一个新服务我请求新服务对象调用一个实例方法.save_in_range!它接受trader_location,循环遍历数据库中的所有位置,并确定两者之间的距离,如果它在服务范围内,则保存ServiceLocations表中的关系:
class Service < ActiveRecord::Base
belongs_to :trader
has_many :service_locations
has_many :locations, through: :service_locations
def save_in_range!
trader_origin = Trader.find(self.trader_id).location
locations = Location.all
locations.each do |location|
if location.distance_from(trader_origin) <= self.range
self.locations << location
end
end
end
end
我的问题是,我真的需要以这种方式做到这一点还是我错过了一些OML魔术?如果不是这是一种有效的方式,还是我编写了糟糕的代码?
答案 0 :(得分:0)
因此,使用您的估算数字,我们可以看到每次trader
更改位置时,您都必须在所有locations
上进行循环,这是一个大约1000的操作。我认为现在准备性能问题是值得的,因为这基本上意味着我们在trader.location
相关操作的成本上有1000倍的乘数,并且这样做并不是那么困难。
我要做几个假设:
location
由两个坐标定义,x / y,长+纬度/球面角度,无论我不会将所有位置加载到Ruby中,只是为了将少量location_ids
保存回记录中。 相反,您应该按两个坐标索引每个位置,并计算SQL查询中的距离。
单独的SQL查询会产生很大的不同,但是您需要进一步优化:
location_ids
location_ids
,只是直接在查询中更新service
locations
上运行距离计算之前,首先按边界矩形过滤(如果世界是2D,则为坐标矩形,如果在地球上,则为球面角矩形)我还没有真正了解具体的实施细节,所以如果您在查找到目前为止我提到的不同组件的资源时请告诉我。