Answers:
您应该阅读该内容,它仍然有效。
您将根据需要调整使用的功能。
基本上:
如果您已经加载了所有条目,例如User.all
,则应该使用length
以避免另一个数据库查询
如果尚未加载任何内容,请使用count
db进行计数查询
如果您不想打扰这些注意事项,请使用size
适合您的
size
您可以在拨打电话时size
(在确定要拨打的电话后)与他们通话。
Comment.create(post_id: post.id)
,您post.comments.size
将不会保持最新,而post.comments.count
会保持最新。因此,请小心。
company.devices.build(:name => "device1"); company.devices.build(:name => "device2")
,然后company.devices.size
并且.length
将包括已构建但尚未保存的对象数,.count
则将仅报告数据库中的计数。
其他答案指出:
count
将执行一个SQL COUNT
查询length
将计算结果数组的长度size
将尝试从两者中选择最合适的一个,以避免过多的查询但是还有一件事。我们注意到一个案例的size
行为与count
/ length
完全不同,我想分享一下,因为这种情况很少被忽略。
如果您:counter_cache
在has_many
关联上size
使用,将直接使用缓存的计数,而根本不会进行额外的查询。
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指南中进行了记录,但是我还是第一次错过了它,或者忘记了它。
_count
列(counter_cache: true
关联上没有指令),也会触发此行为。这已被固定在github.com/rails/rails/commit/e0cb21f5f7
count
。length
。size
...解决将Select count(*)...
查询发送到数据库的问题。如果您不需要数据,而只需要计数,该怎么办。
例如:新消息的计数,仅将要显示页面时的元素总数等。
加载所需的数据,即根据需要查询,然后对其进行计数。使用数据时的处理方式。
示例:满载表的摘要,显示数据的标题等。
它检查是否已加载数据(即已加载到导轨中),然后对其进行计数,否则调用count。(加上其他条目已经提到的陷阱)。
def size
loaded? ? @records.length : count(:all)
end
有什么问题?
如果您未按正确的顺序进行操作,您可能会两次访问数据库(例如,如果在已渲染的表顶部渲染表中的元素数量,则实际上将有2个调用发送到数据库)。
以下策略均调用数据库以执行COUNT(*)
查询。
Model.count
Model.all.size
records = Model.all
records.count
以下方法效率不高,因为它将所有记录从数据库加载到Ruby中,然后Ruby计算集合的大小。
records = Model.all
records.size
如果您的模型具有关联,并且您想查找所属对象的数量(例如@customer.orders.size
),则可以避免数据库查询(磁盘读取)。使用计数器缓存,Rails将使缓存值保持最新,并根据该size
方法返回该值。
Model.all.size
并Model.all.count
产生一个count
在轨道4和上面的查询。真正的优势size
在于,它不产生计数查询,如果该协会已经加载。在Rails 3和更低版本中,我相信Model.all
这不是一个关系,因此所有记录都已加载。该答案可能已过期,建议删除它。
我建议使用尺寸功能。
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是计算记录数的最佳选择。
size
适应反正这种情况,那么什么需要的是有没有length
和count
呢?