Ruby On Rails之length、size及count的区别

前前前.....前段时间,由于自己对length,size,count不熟悉,乱用这计数三兄弟,导致整个网站崩了。而且最主要的是当时还花了很长时间才找到问题的根源(问题藏得太深,各种分析)。

根源

有如下代码

  commodity = Commodity.select('catalog_id', 'brand_name')
  commodity.count

当我使用count的时候会报错,而使用length和size的时候不会报错

count

每次都会去执行sql查询,结果并没有真正的存储在生命周期内部,但是由于activerecord的缓存机制,所以查询一次后,后面的查询都是使用的缓存结果
想得到返回结果的数量时,所以使用count的时候会报错,是因为select('catalog_id', 'brand_name')字段之后,再使用count,生成的sql语句是SELECT COUNT(catalog_id, brand_name),数据库无法知道我们是要根据catalog_id存在的值去做统计,还是根据brand_name存在的值去做统计。如果非要使用count的话,可以在参数里面去声明使用的条件count(:catalog_id)

image.png

length

当我们使用length查询某个集合时,length会将这整个集合全部加载到内存中,再去计算他的长度,当把所有的集合全部放到内存之后,他就可以直接返回集合长度,并且非常快。但是如果数据量大的话,可能就会把内存耗光。所以服务器瘫痪的原因应该就是使用length时,他把commodities表以及inclues进来的表全部加载到内存里面,本来这些数据量就大,所以内存吃了很多,导致瘫痪。

size

比较灵活,其实就是一个三元运算,根据条件去判断使用size还是count,如果加载了集合的话就使用length,没有加载的话就使用count。(如下是size源码)

# File activerecord/lib/active_record/relation.rb, line 260
def size
  loaded? ? @records.length : count(:all)
end

查询语句比较

image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容