我有以下代码:
results = Report.where(:car => 'xxxx').group(:date, :name, :car).select('date, name ,car, info, MAX(price) AS max_price')
for customer in customers
result = results.where(:date => customer.date, :name => customer.name, :car => customer.car).first
.... rest of the code ....
end
我有一个包含大约20,000条记录的数据库,所以我想优化代码并将结果缓存到内存中。 再一次:我的总体意图是使这段代码在时间上更有效率。我希望它比现在运行得更快,我想减少数据库调用量。
我正在考虑让我的初始results
对象成为一个数组。我有一个远程数据库,因此每个.where
查询需要一段时间。当我通过添加results
使.to_a
数组时 - 我将其加载到内存中。所以我认为,它应该更好(但不是很确定)
类似的东西:
results = Report.where(:car => 'xxxx').group(:date, :name, :car)
.select('date, name ,car, info, MAX(price) AS max_price')
.to_a
for customer in customers
result = results.select {|result| result.date == customer.date and result.name == customer.name and result.car == customer.car }
.first
end
答案 0 :(得分:3)
嗯,最好的事情是有一个关联来为客户提取所有报告。在你不能这样做的情况下,我建议只做一个查询而不是n + 1(如问题中所述),如下所示:
results = Report.where(:car => 'xxxx').group(:date, :name, :car)
.select('date, name ,car, info, MAX(price) AS max_price')
.where(:date => customers.map(&:date), :name => customers.map(&:name), :car => customers.map(&:car))
假设客户是一组响应:name
,:car
和:date
方法的对象。
应该注意的一件事是它不能保证它会获取确切客户的报告。为此,您必须通过自己迭代results
对象来验证它。