Ruby on Rails Query Optimization
π Ruby on Rails Query Optimization
Make Your Rails App Lightning-Fast β‘ (The Complete Practical Guide)
βYour app is only as fast as your slowest query.β In Ruby on Rails, poor database queries are the #1 reason for slow applications. Letβs master Query Optimization in Rails β with methods, features, gems, real examples, and common mistakes to avoid π
π What Is Query Optimization in Rails?
Query optimization is the process of reducing database load, execution time, and memory usage by writing efficient ActiveRecord queries and using the right tools.
π‘ Goal: β Fewer queries β Faster queries β Smaller data transfers β Scalable performance
π§ Core Principles of Query Optimization
Before diving into code, remember these golden rules:
1οΈβ£ Avoid unnecessary queries 2οΈβ£ Load only required data 3οΈβ£ Use indexes smartly 4οΈβ£ Prevent N+1 queries 5οΈβ£ Let the database do the heavy work
π§° ActiveRecord Query Optimization Techniques
1οΈβ£ Avoid N+1 Queries π¨
The most common Rails performance killer
β Problem
users = User.all
users.each do |user|
puts user.posts.count
end
π Runs 1 + N queries
β
Solution: includes
users = User.includes(:posts)
users.each do |user|
puts user.posts.size
end
β Loads all data in 2 queries
2οΈβ£ Use select Instead of Fetching Everything π―
β Bad
User.all
β Good
User.select(:id, :email)
π‘ Fetch only what you need β Less memory + faster response
3οΈβ£ Use pluck Instead of Mapping π₯
β Inefficient
User.all.map(&:email)
β Optimized
User.pluck(:email)
β Executes a single optimized SQL query
4οΈβ£ Prefer exists? Over present? or any? β‘
β Slow
User.where(active: true).present?
β Fast
User.exists?(active: true)
β Stops at the first matching record
5οΈβ£ Use count Instead of size or length π
| Method | Behavior |
|---|---|
length |
Loads records |
size |
Conditional |
count |
SQL COUNT |
β Best for performance
User.count
6οΈβ£ Use find_each for Large Data Sets π
β Risky
User.all.each do |user|
process(user)
end
β Memory-Safe
User.find_each(batch_size: 1000) do |user|
process(user)
end
β Prevents memory overflow
7οΈβ£ Use Database Indexes Properly π
Add Index
add_index :users, :email
Composite Index
add_index :orders, [:user_id, :status]
π‘ Index columns used in:
WHEREJOINORDER BY
8οΈβ£ Use joins Instead of includes When Filtering π
β
User.includes(:orders).where(orders: { status: 'paid' })
β
User.joins(:orders).where(orders: { status: 'paid' })
β Faster & cleaner SQL
9οΈβ£ Avoid Ruby-Level Filtering β
β Slow
User.all.select { |u| u.active? }
β Fast
User.where(active: true)
π‘ Always filter in SQL, not Ruby
π Counter Cache for Instant Counts β‘
Setup
add_column :posts, :comments_count, :integer, default: 0
class Comment < ApplicationRecord
belongs_to :post, counter_cache: true
end
β No extra COUNT(*) queries!
π§ Advanced Query Techniques
10οΈβ£ Use EXPLAIN to Analyze Queries π¬
User.where(email: "test@test.com").explain
β Helps identify missing indexes & slow scans
11οΈβ£ Use Scopes for Reusable Queries β»οΈ
scope :active, -> { where(active: true) }
β Cleaner + Optimized + Reusable
π Caching Techniques for Query Optimization
12οΈβ£ Query Caching π§
Rails automatically caches queries per request:
User.find(1)
User.find(1) # Cached
13οΈβ£ Fragment & Russian Doll Caching πͺ
<% cache @user do %>
<%= render @user.posts %>
<% end %>
β Reduces DB hits drastically
π§© Best Gems for Query Optimization
π Bullet β Detect N+1 Queries
gem 'bullet'
β Alerts for:
- N+1 queries
- Unused eager loading
- Missing indexes
π Prosopite β Production-Safe N+1 Detection
gem 'prosopite'
β Lightweight & production-friendly
π PgHero β PostgreSQL Performance Dashboard
gem 'pghero'
β Slow queries β Index suggestions β Query stats
π Goldiloader β Automatic Eager Loading
gem 'goldiloader'
β Smart includes without manual effort
π« Common Query Optimization Mistakes to Avoid
β Using all blindly
β Ignoring N+1 warnings
β Missing indexes on foreign keys
β Loading large datasets in memory
β Filtering in Ruby instead of SQL
β Overusing includes unnecessarily
β Not monitoring slow queries
π Query Optimization Checklist β
β Use includes, joins, preload wisely
β Add proper indexes
β Use pluck, select, exists?
β Analyze queries using EXPLAIN
β Cache aggressively
β Monitor performance regularly
π Final Thoughts
Query Optimization is not optional β itβs mandatory for scalable Rails apps. A well-optimized database can make your app feel 10x faster without adding servers π
βFast code is good. Fast queries are better.β
© Lakhveer Singh Rajput - Blogs. All Rights Reserved.