Ruby-on-rails ActiveRecord:大小与数量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6083219/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ActiveRecord: size vs count
提问by Andrew
In Rails, you can find the number of records using both Model.sizeand Model.count. If you're dealing with more complex queries is there any advantage to using one method over the other? How are they different?
在 Rails 中,您可以同时使用Model.size和来查找记录数Model.count。如果您正在处理更复杂的查询,使用一种方法比使用另一种方法有什么优势吗?它们有何不同?
For instance, I have users with photos. If I want to show a table of users and how many photos they have, will running many instances of user.photos.sizebe faster or slower than user.photos.count?
例如,我有用户有照片。如果我想显示一个用户表以及他们有多少张照片,运行多个实例user.photos.size会比 快还是慢user.photos.count?
Thanks!
谢谢!
回答by apneadiving
You should read that, it's still valid.
你应该阅读它,它仍然有效。
You'll adapt the function you use depending on your needs.
您将根据需要调整您使用的功能。
Basically:
基本上:
if you already load all entries, say
User.all, then you should uselengthto avoid another db queryif you haven't anything loaded, use
countto make a count query on your dbif you don't want to bother with these considerations, use
sizewhich will adapt
如果您已经加载了所有条目,例如
User.all,那么您应该使用length以避免另一个数据库查询如果您没有加载任何内容,请使用
count对您的数据库进行计数查询如果您不想为这些考虑而烦恼,请使用
sizewhich 将适应
回答by lime
As the other answers state:
正如其他答案所述:
countwill perform an SQLCOUNTquerylengthwill calculate the length of the resulting arraysizewill try to pick the most appropriate of the two to avoid excessive queries
count将执行 SQLCOUNT查询length将计算结果数组的长度size将尝试选择两者中最合适的以避免过度查询
But there is one more thing. We noticed a case where sizeacts differently to count/lengthaltogether, and I thought I'd share it since it is rare enough to be overlooked.
但还有一件事。我们注意到一个案例size与count/length完全不同,我想我会分享它,因为它很少被忽视。
If you use a
:counter_cacheon ahas_manyassociation,sizewill 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
如果
:counter_cache在has_many关联上使用 a ,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
This behaviour is documented in the Rails Guides, but I either missed it the first time or forgot about it.
这种行为记录在Rails 指南中,但我要么第一次错过了它,要么忘记了它。
回答by jvalanen
Sometimes size"picks the wrong one" and returns a hash(which is what countwould do)
有时size“选择错误的”并返回一个哈希值(这是count会做的)
In that case, use lengthto get an integerinstead of hash.
在这种情况下,使用length获取整数而不是hash。
回答by Dennis
The following strategies all make a call to the database to perform a COUNT(*)query.
以下策略都调用数据库来执行COUNT(*)查询。
Model.count
Model.all.size
records = Model.all
records.count
The following is not as efficient as it will load all records from the database into Ruby, which then counts the size of the collection.
下面的代码效率不高,因为它将数据库中的所有记录加载到 Ruby 中,然后计算集合的大小。
records = Model.all
records.size
If your models have associations and you want to find the number of belonging objects (e.g. @customer.orders.size), you can avoid database queries (disk reads). Use a counter cacheand Rails will keep the cache value up to date, and return that value in response to the sizemethod.
如果您的模型有关联,并且您想找到所属对象的数量(例如@customer.orders.size),您可以避免数据库查询(磁盘读取)。使用计数器缓存,Rails 将保持缓存值最新,并返回该值以响应该size方法。
回答by estani
tl;dr
tl;博士
- If you know you won't be needing the data use
count. - If you know you will use or have used the data use
length. - If you don't know what you are doing, use
size...
- 如果您知道不需要数据,请使用
count. - 如果您知道您将使用或已经使用该数据,请使用
length. - 如果您不知道自己在做什么,请使用
size...
count
数数
Resolves to sending a Select count(*)...query to the DB. The way to go if you don't need the data, but just the count.
解决向数据库发送Select count(*)...查询。如果您不需要数据,而只需要计数,那么要走的路。
Example: count of new messages, total elements when only a page is going to be displayed, etc.
示例:新消息的计数、仅显示页面时的总元素等。
length
长度
Loads the required data, i.e. the query as required, and then just counts it. The way to go if you are using the data.
加载所需的数据,即根据需要进行查询,然后对其进行计数。如果您正在使用数据,则要走的路。
Example: Summary of a fully loaded table, titles of displayed data, etc.
示例:完全加载的表的摘要、显示数据的标题等。
size
尺寸
It checks if the data was loaded (i.e. already in rails) if so, then just count it, otherwise it calls count. (plus the pitfalls, already mentioned in other entries).
它检查数据是否已加载(即已经在 Rails 中),如果是,则对其进行计数,否则调用计数。(加上其他条目中已经提到的陷阱)。
def size
loaded? ? @records.length : count(:all)
end
What's the problem?
有什么问题?
That you might be hitting the DB twice if you don't do it in the right order (e.g. if you render the number of elements in a table on top of the rendered table, there will be effectively 2 calls sent to the DB).
如果您没有按照正确的顺序进行操作,您可能会两次访问 DB(例如,如果您在渲染表的顶部渲染表中的元素数量,则实际上将有 2 次调用发送到 DB)。
回答by manthan andharia
I recommended using the size function.
我建议使用 size 函数。
class Customer < ActiveRecord::Base
has_many :customer_activities
end
class CustomerActivity < ActiveRecord::Base
belongs_to :customer, counter_cache: true
end
Consider these two models. The customer has many customer activities.
考虑这两个模型。客户有许多客户活动。
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.
如果您在 has_many 关联上使用 :counter_cache,则 size 将直接使用缓存的计数,而根本不会进行额外的查询。
Consider one example: in my database, one customer has 20,000 customer activities and I try to count the number of records of customer activities of that customer with each of count, length and size method. here below the benchmark report of all these methods.
考虑一个例子:在我的数据库中,一个客户有 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)
so I found that using :counter_cache Size is the best option to calculate the number of records.
所以我发现使用 :counter_cache Size 是计算记录数的最佳选择。

