执行ActiveRecord::使用即时加载的计算会导致多个数据库查询吗?

时间:2022-10-05 14:45:13

My confusion stems from this question, where OP has a model like

我的困惑源于这个问题,OP有一个类似的模型

class Quote < ActiveRecord::Base
  has_many :items
  def calc_price
    sum = 0
    #logic for summation
  end
end

In the answers, a couple of people have suggested using the sum method directly for calculating the sum of attributes

在回答中,一些人建议使用sum方法直接计算属性的和

def total_price
  items.sum('price')
end

If I eager load data using Quote.includes(:items).find(:all), does the sum happen at the database's end, or does it use the objects already loaded in memory? If it uses the objects already loaded in memory, then the calculations are not being offloaded to the database.

如果我使用quote.include (:items).find(:all)加载数据,那么求和是在数据库的末尾发生的,还是使用已经加载到内存中的对象?如果它使用已经加载到内存中的对象,那么计算就不会被卸载到数据库中。

Will it make the database query twice, once to preload, next to sum up the prices?

它会使数据库查询两次,一次是预加载,然后是价格的总和?

Extending the same logic to all ActiveRecord::Calculations, Will I hit my database everytime if I do a count or average or other such methods?

将相同的逻辑扩展到所有ActiveRecord:: calculate时,如果每次执行count或average或其他此类方法,我是否会访问数据库?

1 个解决方案

#1


4  

ActiveRecord::Calculations (which includes sum, count, average) will hit the database even if the items are eager-loaded. For e.g.

ActiveRecord:::计算(包括sum、count、average)即使项目是紧急加载的,也会对数据库造成影响。如。

 quotes = Quote.includes(:items).find(:all)
 # two queries one to fetch quotes and one to fetch all associated items

 items = quotes.first.items
 # no query as items are eager loaded

 total_price = quotes.first.items.sum(:price)
 # one query to get sum of item prices for the first quote
 # summation is done by the database

To check this, run the rails console and log to the console using ActiveRecord::Base.logger = Logger.new(STDOUT). You can then see what db queries are being made for each method.

要检查这一点,请运行rails控制台并使用ActiveRecord: Base登录到控制台。记录器= Logger.new(STDOUT)。然后,您可以看到对每个方法进行了哪些db查询。

#1


4  

ActiveRecord::Calculations (which includes sum, count, average) will hit the database even if the items are eager-loaded. For e.g.

ActiveRecord:::计算(包括sum、count、average)即使项目是紧急加载的,也会对数据库造成影响。如。

 quotes = Quote.includes(:items).find(:all)
 # two queries one to fetch quotes and one to fetch all associated items

 items = quotes.first.items
 # no query as items are eager loaded

 total_price = quotes.first.items.sum(:price)
 # one query to get sum of item prices for the first quote
 # summation is done by the database

To check this, run the rails console and log to the console using ActiveRecord::Base.logger = Logger.new(STDOUT). You can then see what db queries are being made for each method.

要检查这一点,请运行rails控制台并使用ActiveRecord: Base登录到控制台。记录器= Logger.new(STDOUT)。然后,您可以看到对每个方法进行了哪些db查询。