From a developers perspective, I have shared some tips to easily improve the performance of rails applications. We are going to look into techniqes that greatly improve the application’s performance.
- Querying database
- Rendering partials
1. Querying database
a.) Avoiding Queries within loop
Using queries within loop greatly reduces the performance by querying the database numerous times rather than a single time.
b.) Avoiding N+1 Queries
Most ORMs have lazy-loading enabled by default, so queries are issued for the parent record, and then one query for each child record. We can fix N+1 query problem by using pro-load child record when querying the database for parent record and we can use the bullet to gem to discover N+1 queries.
c.) Using Counter Cache
A counter cache will be used in few places but it slightly improves the performance. We can use counter cache to store child records count which avoids querying database for the count of child records.
d.) SQL caching
Query caching is a Rails feature that caches the result set returned by each query. If Rails encounters the same query again for that request, it will use the cached result set as opposed to running the query against the database again.The second time the same query is run against the database, it’s not actually going to hit the database. The first time the result is returned from the query it is stored in the query cache (in memory) and the second time it’s pulled from memory.
However, it’s important to note that query caches are created at the start of an action and destroyed at the end of that action and thus persist only for the duration of the action. If you’d like to store query results in a more persistent fashion, you can with low level caching.
e.) Low-level Caching
Sometimes we need to cache a particular value or query result instead of caching view fragments. Rails caching mechanism works great for storing any kind of information.The most efficient way to implement low-level caching is using the Rails.cache.fetch method. This method does both reading and writing to the cache. When passed only a single argument, the key is fetched and value from the cache is returned. If a block is passed, the result of the block will be cached to the given key and the result is returned.
f.) Using search engines
Using search engines will highly increase the performance by quickly get data from the database. Fast search is one of the main advantages of search engines and search across multiple fields using search engines more efficient than SQL. Following are some of the search engines available in rails
– Elastic search
– Thinking Sphinx
Most of the search engines are not ruby based but we can use them by Tire(Elastic search), Thinking-Sphinx(Thinking sphinx) gems.
g.) Using Third party services to monitoring and improving application performance
Third party services like ‘new relica’ depict the clear picture of time taken for every process(querying a database, rendering partials) in processing request. By using new relic we can easily discover and fix problems like slow response time, most time-consuming request.
h.) SQL Indexing
Indexing is more useful in using both text-based search and SQL-based search. SQL index is a data structure that improves the speed of operations on a database table. For every index on a table, there is a penalty both when inserting and updating rows. Indexes also take up space on disk and in memory, which can affect the efficiency of queries. Finally, having too many indexes can cause databases to choose between them poorly, actually harming performance rather than improving it. So while indexing it is important to choose carefully how to index our data.
Note: Don’t index every table columns and use where ever index is needed(frequently used tables). There is a performance hit with indexes. Although select queries can be significantly faster, inserts and updates are marginally slower because there is overhead in maintaining the index. However, the small impact (milliseconds) during an insert is usually a small price to pay for what could be seconds (or even minutes) saved on certain queries.
2. Rendering partials
a.) Avoiding queries in view side
Avoiding queries in view side will not improve performance greatly but according to rails architecture writing queries in view side is bad practice.
b.) Using Fragment caching
Rails provide a mechanism called Fragment Caching for cache different parts of the page and it will be expired differently. Fragment Caching allows a fragment of view logic to be wrapped in a cache block and served out of the cache store when the next request comes in.
Note: It may give unexpected result when failed to update the latest content.
I have shared some easily used processes for improving Rails application performance and it’s not possible to cover everything in Ruby on Rail performance optimization in one post and I will share more things in a later post. I have only shared the usage and have not mentioned where to use them. Before using the above techniques, a good understanding is required, otherwise it may lead to unexpected results.