在Rails中,您可以使用这两种Model找到记录的数量。和Model.count。如果要处理更复杂的查询,使用一种方法比另一种方法有什么优势吗?它们有什么不同?
例如,我有带有照片的用户。如果我想显示一个用户表以及他们有多少张照片,运行多个user.photos.size实例会比user.photos.count快还是慢?
谢谢!
在Rails中,您可以使用这两种Model找到记录的数量。和Model.count。如果要处理更复杂的查询,使用一种方法比另一种方法有什么优势吗?它们有什么不同?
例如,我有带有照片的用户。如果我想显示一个用户表以及他们有多少张照片,运行多个user.photos.size实例会比user.photos.count快还是慢?
谢谢!
当前回答
你应该读一下,它仍然有效。
您将根据需要调整所使用的功能。
基本上:
如果你已经加载了所有的条目,就说User。所有,那么你应该使用长度来避免另一个db查询 如果你没有加载任何东西,使用count在你的db上进行count查询 如果您不想为这些考虑而烦恼,请使用能够适应的大小
其他回答
这里有一个流程图来简化你的决策过程。希望能有所帮助。
来源:Rails中长度、大小和计数方法之间的差异
博士tl;
如果您知道您不需要数据,请使用计数。 如果您知道您将使用或已经使用的数据使用长度。 如果你不知道它在哪里使用,或者速度差异可以忽略不计,使用size…
数
解析发送一个选择计数(*)…查询到数据库。如果你不需要数据,只要计数就可以了。
示例:新消息的计数,只显示一个页面时的元素总数,等等。
长度
加载所需的数据,即根据需要进行查询,然后对其进行计数。如果你在使用这些数据。
示例:一个满载表的摘要、显示数据的标题等。
size
它检查数据是否已加载(即已经在rails中),如果是,则只计算它,否则调用count。(加上陷阱,已经在其他条目中提到了)。
def size
loaded? ? @records.length : count(:all)
end
有什么问题吗?
如果你没有按正确的顺序做,你可能会击中DB两次(例如,如果你在渲染表的顶部渲染表中的元素数量,实际上会有2个调用发送到DB)。
你应该读一下,它仍然有效。
您将根据需要调整所使用的功能。
基本上:
如果你已经加载了所有的条目,就说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指南中有记录,但我不是第一次就错过了,就是忘记了。