Ruby on Rails Optimization – How to Reduce Database Calls

databaseefficiencyoptimizationruby-on-rails

What's the best way to optimize a Rails app where you need to pull info from the database for a collection of items?

For example, if I am building an online forum system… I would have a number of Posts and the posts would have_many :recommendations and :comments and :favorites. When I display the posts in my view, I might need to display this info – like a count of how many comments there are, and whether or not my current user has favorited/recommended the post.

I was playing around with this and it seems there are a huge number of DB queries being executed! First I'm grabbing my collection of posts – then, iterating through each one, I am going to the comments table, the favorites table, etc… to get counts or see if records exist for that particular post. So for every post I have, I'm executing 3 separate queries!

Is there a more efficient way to get this data, or are tons of queries like this normal for a scenario like I describe?

Best Answer

If information like how many comments, up-votes, favorites a post have is frequently used, you are better off storing these counts somewhere; querying the DB every time for number of comments in a post, number of followers a user have, etc. may quite soon become your performance bottleneck.

Two common approaches exist:

  1. Add column/field for Posts in the database that store the comment count. when new comments are added, increase that counter field by one (synchronously), or update that count every hour/day (asynchronously).

  2. Use cache (memcache, redis) to store those numbers to reduce database queries. Memory cache are usually required for high traffic sites, anyway.

Either way you can weave it into your ORM / Abstraction Layer, so there won't be too much additional code involved. For advantages/disadvantages, there are plenty of discussions/debates around this issue on the net. Google it for thorough and detailed explanations :)

Related Topic