Answers:
您应该阅读该内容,它仍然有效。
您将根据需要调整使用的功能。
基本上:
如果您已经加载了所有条目,例如User.all,则应该使用length以避免另一个数据库查询
如果尚未加载任何内容,请使用countdb进行计数查询
如果您不想打扰这些注意事项,请使用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呢?