在Rails中优化查询

时间:2017-09-21 15:03:31

标签: ruby-on-rails ruby

我有以下代码:

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

1 个答案:

答案 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对象来验证它。