OR REACH ME ON

    Optimizing SQL Queries in Rails: Real Examples from Production

    At some point in my career, I hit the classic problem: everything worked fine in development, but once real data came in, the app slowed down. The culprit? Inefficient SQL queries.

    Rails makes it easy to query the database, but it’s also easy to write code that looks fine yet performs poorly. Here are some real lessons from production.

    The N+1 Query Problem

    Example (Bad)

    				
    					# Controller
    @users = User.all
    
    # View
    <% @users.each do |user| %>
      <%= user.posts.count %>
    <% end %>
    				
    			

    This triggers 1 query for users + 1 query per user = N+1 queries.

    Fix (Good)

    				
    					@users = User.includes(:posts)
    
    <% @users.each do |user| %>
      <%= user.posts.size %>
    <% end %>
    				
    			

    Now, Rails loads all posts in two queries total.

    Selecting Only What You Need

    Example (Bad)

    				
    					users = User.all
    users.each { |u| puts u.email }
    				
    			

    This loads entire rows, even columns we don’t need.

    Fix (Good)

    				
    					users = User.select(:id, :email)
    users.each { |u| puts u.email }
    				
    			

    Lighter queries = faster performance.

    Using Indexes

    Example (Bad)

    				
    					User.where(email: "test@example.com")
    				
    			

    Without an index on email, this scans the entire table.

    Fix (Good)

    				
    					# migration
    add_index :users, :email, unique: true
    				
    			

    Now lookups are instant.

    Batching Large Queries

    Example (Bad)

    				
    					User.all.each do |user|
      process(user)
    end
    				
    			

    This loads all users into memory.

    Fix (Good)

    				
    					User.find_each(batch_size: 1000) do |user|
      process(user)
    end
    				
    			

    Memory stays low, queries are batched.

    Measuring Queries

    Use Rails logging or bullet gem to spot N+1 queries:

    				
    					gem 'bullet'
    				
    			

    It warns you when eager loading is missing.

    🎯 Final Thoughts

    Optimizing SQL in Rails isn’t about writing raw queries — it’s about being mindful of how ActiveRecord works. The three biggest wins I’ve seen in real projects were:

    1. Fixing N+1 queries

    2. Adding the right indexes

    3. Batching data loads

    Once I applied these consistently, page load times dropped from seconds to milliseconds — a real turning point in my growth as a backend engineer.