美文网首页Rails
Ruby On Rails之length、size及count的

Ruby On Rails之length、size及count的

作者: SSS_ruby | 来源:发表于2019-10-17 22:28 被阅读0次

    前前前.....前段时间,由于自己对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

    相关文章

      网友评论

        本文标题:Ruby On Rails之length、size及count的

        本文链接:https://www.haomeiwen.com/subject/mzhbmctx.html