Ruby on rails Rails计数器不带任何关联地缓存Model.count,以加快选择计数(*)

Ruby on rails Rails计数器不带任何关联地缓存Model.count,以加快选择计数(*),ruby-on-rails,ruby-on-rails-3,ruby-on-rails-5,Ruby On Rails,Ruby On Rails 3,Ruby On Rails 5,我正在使用Model.count对我的一个模型中的行进行合计,我有点担心性能,因为最终,这个模型会变得非常大,因此,SELECT count(*)非常慢 是否有一种方法可以在不使用:归属关系的情况下使用计数器\u缓存?还是另一种性能友好的行计数方法?我考虑制作另一个模型,就是这样存储计算结果的模型,但不确定这是最好的方法。看一看 具体来说,您需要查看有关缓存存储的部分。使用缓存存储,您可以将任意内容的值存储到缓存中 例如,您可以在名为get_count的模型上调用一个方法,该方法最初由计数填充,

我正在使用
Model.count对我的一个模型中的行进行合计,我有点担心性能,因为最终,这个模型会变得非常大,因此,
SELECT count(*)
非常慢

是否有一种方法可以在不使用
:归属关系的情况下使用
计数器\u缓存
?还是另一种性能友好的行计数方法?我考虑制作另一个模型,就是这样存储计算结果的模型,但不确定这是最好的方法。

看一看 具体来说,您需要查看有关缓存存储的部分。使用缓存存储,您可以将任意内容的值存储到缓存中

例如,您可以在名为get_count的模型上调用一个方法,该方法最初由计数填充,但在创建回调后增加1。如果没有必要让它保持最新,你可以每x分钟更新一次,这样你就基本准确了


我个人使用memcache来存储类似的东西。只要确保缓存根据需要保持最新即可

如果您想要维护计数器,无论是使用
counter\u cache
还是手动操作,Rails都将使用回调来维护计数器,这将在创建/销毁新子体时增加/减少计数器

我不知道有什么方法可以在不使用
归属
关系的情况下存储
计数器缓存
,因为只有父级可以存储子级的计数

称重性能 如果您的表将变得“大”,请使用大量行填充测试数据库,然后开始使用
EXPLAIN
运行一些SQL查询,以获得数据库查询的性能。查看使用
counter\u cache
创建/销毁记录时的性能影响是否被您首先需要访问这些计数器的频率所抵消

如果计数器不需要总是100%准确,您可以改为使用
cron
作业或后台工作程序定期更新缓存

总之:

  • 如果需要足够的计数器来抵消创建/销毁记录所需的稍长时间,则应仅使用计数器缓存
  • 据我所知,使用
    计数器\u缓存
    与使用回调的手动替代方案相比,不太可能对性能造成太大的损害
  • 如果缓存不需要精确,请利用这一点,减少计算次数

  • 比创建
    缓存
    模型更简单的是只使用
    Rails.Cache

    Rails.cache.read("elephant_count") #=> nil
    Rails.cache.write("elephant_count", 1) #=> true
    Rails.cache.read("elephant_count") #=> 1
    
    Rails默认使用文件存储(tmp/cache)

    然后,您可以在创建
    和销毁
    钩子后,将Rails.cache.write增量和减量放入模型的
    中,并通过调用Rails.cache.read覆盖
    model.size

    只要Rails首次初始化,您就可以通过在config/initializers中放置一个名为
    initialize\u cache.rb
    的文件来初始化缓存,该文件包含:

    Rails.cache.write('elephant_count', 0) if Rails.cache.read('elephant_count').nil?
    

    像这样定义一个
    CachedCount
    关注点怎么样

    模块缓存计数
    扩展ActiveSupport::关注点
    包括做
    创建后:增量缓存计数
    销毁后:减少缓存计数
    结束
    类方法做什么
    def计数
    如果已缓存\u计数,则返回已缓存\u计数
    Rails.cache.write(cached\u count\u key,super)
    Rails.cache.read(cached_count_key)| | super#回退,因为在某些Rails环境中。Rails.cache可能不可用
    结束
    def缓存的\u计数\u键
    “#{model_name.collection}\u count”
    结束
    def缓存单位计数
    Rails.cache.read(缓存的\u计数\u键)
    结束
    结束
    def增量缓存计数
    返回self.class.count,除非self.class.cached\u count
    Rails.cache.write(self.class.cached\u count\u键,self.class.cached\u count+1)
    结束
    def减量\u缓存\u计数
    返回self.class.count,除非self.class.cached\u count
    Rails.cache.write(self.class.cached\u count\u键,self.class.cached\u count-1)
    结束
    结束
    
    然后将其包括在众多模型中:

    类MyNumerousModel
    包含缓存计数
    # [...]
    结束
    
    现在,每次调用
    MyNumerousModel.count
    时,实际上是在调用关注点中的类方法。当您创建或销毁MyNumerousModel的一个实例时,创建后的
    和销毁后的
    回调负责更新
    MyNumerousModel.cached\u count