在Rails中,您可以使用这两种Model找到记录的数量。和Model.count。如果要处理更复杂的查询,使用一种方法比另一种方法有什么优势吗?它们有什么不同?

例如,我有带有照片的用户。如果我想显示一个用户表以及他们有多少张照片,运行多个user.photos.size实例会比user.photos.count快还是慢?

谢谢!


当前回答

这里有一个流程图来简化你的决策过程。希望能有所帮助。

来源:Rails中长度、大小和计数方法之间的差异

其他回答

你应该读一下,它仍然有效。

您将根据需要调整所使用的功能。

基本上:

如果你已经加载了所有的条目,就说User。所有,那么你应该使用长度来避免另一个db查询 如果你没有加载任何东西,使用count在你的db上进行count查询 如果您不想为这些考虑而烦恼,请使用能够适应的大小

以下策略都调用数据库来执行COUNT(*)查询。

Model.count

Model.all.size

records = Model.all
records.count

下面的方法效率不高,因为它会将所有记录从数据库加载到Ruby中,然后计算集合的大小。

records = Model.all
records.size

如果您的模型有关联,并且您想要找到属于对象的数量(例如@customer.orders.size),您可以避免数据库查询(磁盘读取)。使用计数器缓存,Rails将保持缓存值为最新,并返回该值以响应size方法。

正如其他答案所述:

count将执行SQL count查询 Length将计算结果数组的长度 Size将尝试从两者中选择最合适的,以避免过多的查询

但还有一件事。我们注意到一个情况,大小对计数/长度的作用完全不同,我想我应该分享它,因为它很少被忽视。

If you use a :counter_cache on a has_many association, size will use the cached count directly, and not make an extra query at all. class Image < ActiveRecord::Base belongs_to :product, counter_cache: true end class Product < ActiveRecord::Base has_many :images end > product = Product.first # query, load product into memory > product.images.size # no query, reads the :images_count column > product.images.count # query, SQL COUNT > product.images.length # query, loads images into memory

这种行为在Rails指南中有记录,但我不是第一次就错过了,就是忘记了。

有时size“选择了错误的值”并返回哈希值(这就是count所做的)

在这种情况下,使用length来获取整数而不是散列。

我建议使用size函数。

class Customer < ActiveRecord::Base
  has_many :customer_activities
end

class CustomerActivity < ActiveRecord::Base
  belongs_to :customer, counter_cache: true
end

考虑这两个模型。客户有许多客户活动。

如果在has_many关联上使用:counter_cache, size将直接使用缓存的计数,而根本不进行额外的查询。

举个例子: 在我的数据库中,一个客户有20,000个客户活动,我尝试用每种计数,长度和大小方法计算该客户的客户活动记录的数量。下面是所有这些方法的基准测试报告。

            user     system      total        real
Count:     0.000000   0.000000   0.000000 (  0.006105)
Size:      0.010000   0.000000   0.010000 (  0.003797)
Length:    0.030000   0.000000   0.030000 (  0.026481)

所以我发现使用:counter_cache Size是计算记录数量的最佳选择。