Rails counter_cache

I am summarizing the lines in one of my models using Model.count and a little concerned about performance, as this model will be very large in the end. Is there a way to use counter_cache w / o relation: belongs_to? Or another convenient way to count strings? I thought about creating another model, only one where I store computations like this, but not sure which is the best way.

+6
source share
3 answers

Even more trivial than creating a Cache model, just use Rails.cache .

 Rails.cache.read("elephant_count") #=> nil Rails.cache.write("elephant_count", 1) #=> true Rails.cache.read("elephant_count") #=> 1 

Rails uses the default file storage (tmp / cache).

Then you can simply put the value of Rails.cache.write and reduce it into the after_create and after_destroy and override Model.size when calling Rails.cache.read.

You can initialize the cache whenever Rails is first initialized by placing a file called initialize_cache.rb in config / initializers containing:

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

If you want to have a supported counter at all, using counter_cache or doing it manually, Rails will support your counters with callbacks, which will increase / decrease the counter when a new child is created / destroyed.

I am not aware of counter_cache storage counter_cache without using the belongs_to relationship, because only the parent can store the number of children.

Weight Performance

If your table is β€œlarge”, populate the test database with a large number of rows, and then run some SQL queries using EXPLAIN to get database query performance. See if the performance achieved by creating / destroying a record using counter_cache is offset by how often you have to access these counters in the first place.

If the counter should not be 100% accurate, you can periodically update caches using cron job or background worker.

In short:

  • You only need to use counter_cache if you need these counters to compensate for a bit more time spent on creating / deleting the record.
  • Using counter_cache compared to the manual alternative using callbacks, as far as I know, is unlikely to result in a significant performance loss.
  • If the cache does not need to be accurate, take advantage of this and perform calculations less frequently.
+9
source

Take a look at http://guides.rubyonrails.org/caching_with_rails.html In particular, you need to look at the section on cache repositories. Using cache repositories, you can store values ​​in the cache for arbitrary things.

For example, you might have a method called in a model called get_count, which will be filled first in the account, but incremented by 1 with the after_create callback. If you do not need to update it, you can update it every x minutes so that you are mostly accurate.

I personally use memcache as a store for such things. Just make sure you update the cache according to your needs.

+4
source

Source: https://habr.com/ru/post/887880/


All Articles