Rails counter_cache

时间:2011-05-12 01:04:48

标签: ruby-on-rails ruby-on-rails-3

我使用Model.count总计了我的一个模型中的行,并且有点担心性能,因为最终,这个模型会变得非常大。有没有办法使用counter_cache没有:belongs_to关系?还是另一种性能友好的计算行数的方法?我想要制作另一个模型,只是我存储这样的计算但不确定这是最好的方法。

3 个答案:

答案 0 :(得分:13)

制作Cache模型比使用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增量和减量放入模型的after_createafter_destroy钩子中,并通过调用Rails.cache.read覆盖Model.size

您可以在Rails首次初始化时初始化缓存,方法是在config / initializers中放置一个名为initialize_cache.rb的文件,其中包含:

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

答案 1 :(得分:10)

如果你想拥有一个维护的计数器,无论是使用counter_cache还是手动执行,Rails都会使用回调来维护你的计数器,这会在创建/销毁新的后代时增加/减少计数器。

我不知道在不使用counter_cache关系的情况下存储belongs_to的方法,因为只有父级才能存储子级的数量。

称重性能

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

如果计数器始终不需要100%准确,则可以使用cron作业或后台工作人员定期更新缓存。

总结:

  1. 如果您需要这些计数器足以抵消创建/销毁记录所需的稍长时间,那么您应该只使用counter_cache。
  2. 据我所知,使用counter_cache vs使用回调的手动替代方案不太可能对性能造成太大损害。
  3. 如果缓存不需要准确,请利用它并减少执行次数。

答案 2 :(得分:5)

看看http://guides.rubyonrails.org/caching_with_rails.html 具体来说,您需要查看有关缓存存储的部分。使用缓存存储,您可以将值存储到缓存中以执行任意操作。

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

我个人使用memcache作为这样的东西的商店。只需确保根据需要保持缓存最新。