Bird
Raised Fist0
Ruby on Railsframework~8 mins

Database query optimization in Ruby on Rails - Performance & Optimization

Choose your learning style10 modes available
Performance: Database query optimization
HIGH IMPACT
This affects how fast the page loads data from the database and how quickly the server responds to user requests.
Fetching related records in a Rails app
Ruby on Rails
posts = Post.includes(:comments).all
posts.each do |post|
  puts post.comments.size
end
Loads all comments in one query, avoiding multiple database hits.
📈 Performance Gainreduces queries from N+1 to 2, significantly lowering server response time
Fetching related records in a Rails app
Ruby on Rails
posts = Post.all
posts.each do |post|
  puts post.comments.count
end
This triggers a separate database query for each post to count comments, causing many queries.
📉 Performance Costtriggers N+1 queries where N is number of posts, increasing server response time
Performance Comparison
PatternDatabase QueriesData TransferredServer Response TimeVerdict
N+1 queriesMany small queries (N+1)More data due to repeated queriesHigh due to multiple DB hits[X] Bad
Eager loading with includesFew queries (usually 2)Less repeated dataLower due to fewer DB hits[OK] Good
Selecting all columnsSingle queryLarge data sizeMedium due to data size[!] OK
Selecting needed columnsSingle queryMinimal data sizeLow due to less data[OK] Good
Unindexed where clauseSingle queryDepends on dataHigh due to full table scan[X] Bad
Indexed where clauseSingle queryDepends on dataLow due to index use[OK] Good
Rendering Pipeline
Database query optimization reduces server processing time before HTML is sent to the browser, improving the critical rendering path by delivering data faster.
→Server Processing
→Network Transfer
→First Contentful Paint
⚠️ BottleneckServer Processing due to slow or excessive database queries
Core Web Vital Affected
LCP
This affects how fast the page loads data from the database and how quickly the server responds to user requests.
Optimization Tips
1Avoid N+1 queries by using eager loading (includes).
2Select only the columns you need to reduce data size.
3Add indexes on columns used frequently in filters.
Performance Quiz - 3 Questions
Test your performance knowledge
What is the main performance problem with N+1 queries in Rails?
AIt triggers many database queries, slowing server response
BIt loads too many columns in one query
CIt causes layout shifts in the browser
DIt increases CSS selector complexity
DevTools: Network and Performance panels
How to check: Open DevTools, go to Network tab, reload page and check time for API/database calls; use Performance tab to record and analyze server response times.
What to look for: Look for long waiting times on database calls and multiple repeated requests indicating N+1 queries.

Practice

(1/5)
1. What is the main benefit of using includes in Rails queries?
easy
A. It loads associated records in fewer database queries to improve performance.
B. It deletes unused records from the database automatically.
C. It encrypts data before saving to the database.
D. It creates new database tables for associations.

Solution

  1. Step 1: Understand what includes does

    includes loads related records in one or fewer queries to avoid repeated database hits.
  2. Step 2: Identify the benefit

    This reduces the number of queries, speeding up the app and saving server resources.
  3. Final Answer:

    It loads associated records in fewer database queries to improve performance. -> Option A
  4. Quick Check:

    Using includes reduces queries = B [OK]
Hint: Think: fewer queries means faster loading [OK]
Common Mistakes:
  • Confusing includes with deleting records
  • Thinking includes encrypts data
  • Assuming includes creates tables
2. Which of the following is the correct syntax to select only the name and email columns from a User model in Rails?
easy
A. User.find(:name, :email)
B. User.where(:name, :email)
C. User.includes(:name, :email)
D. User.select(:name, :email)

Solution

  1. Step 1: Recall the method to choose specific columns

    The select method specifies which columns to retrieve from the database.
  2. Step 2: Check the syntax

    User.select(:name, :email) correctly selects only the name and email columns.
  3. Final Answer:

    User.select(:name, :email) -> Option D
  4. Quick Check:

    Select columns = select method = D [OK]
Hint: Use select to pick columns, not where or includes [OK]
Common Mistakes:
  • Using where instead of select for columns
  • Using includes to select columns
  • Using find with multiple columns
3. Given the following Rails code:
posts = Post.includes(:comments).where(published: true)

What is the main effect of this query?
medium
A. It loads all posts and their comments, regardless of published status.
B. It loads only comments for published posts but not the posts themselves.
C. It loads only published posts and their comments efficiently in fewer queries.
D. It deletes unpublished posts and their comments.

Solution

  1. Step 1: Analyze the query filters and includes

    The where(published: true) filters posts to only those published. includes(:comments) loads comments with posts efficiently.
  2. Step 2: Understand the combined effect

    The query fetches published posts and their comments in fewer database queries, improving performance.
  3. Final Answer:

    It loads only published posts and their comments efficiently in fewer queries. -> Option C
  4. Quick Check:

    Filter + includes = efficient published posts with comments = C [OK]
Hint: Filter first, then includes loads related data efficiently [OK]
Common Mistakes:
  • Thinking includes ignores the where filter
  • Assuming comments load without posts
  • Confusing includes with deletion
4. Identify the problem in this Rails query and how to fix it:
users = User.where(active: true).includes(:posts).select(:name)
medium
A. The select excludes the primary key (:id), causing posts not to load; fix by including :id in select.
B. The includes method is used incorrectly; replace it with joins.
C. The where clause should come after select to filter correctly.
D. The query will delete inactive users; remove where clause.

Solution

  1. Step 1: Understand select limits columns

    The select(:name) limits columns returned, but the primary key id is missing.
  2. Step 2: Effect on includes

    Without the primary key, Rails cannot load associated posts properly with includes.
  3. Step 3: Fix the query

    Add the primary key column (e.g., :id) to the select list to allow loading posts.
  4. Final Answer:

    The select excludes the primary key (:id), causing posts not to load; fix by including :id in select. -> Option A
  5. Quick Check:

    Select must include primary key for includes to work = A [OK]
Hint: Always select primary keys when using includes [OK]
Common Mistakes:
  • Removing primary key from select breaks associations
  • Replacing includes with joins unnecessarily
  • Changing where order incorrectly
5. You want to optimize a query to fetch Order records with their Customer and only the total_price and created_at fields from orders. Which Rails query is best for this optimization?
hard
A. Order.joins(:customer).select('orders.total_price, orders.created_at, customers.*')
B. Order.includes(:customer).select(:total_price, :created_at, :customer_id)
C. Order.includes(:customer).select(:total_price, :created_at)
D. Order.all.select(:total_price, :created_at)

Solution

  1. Step 1: Identify needed fields and associations

    You want orders with only total_price and created_at, plus associated customers.
  2. Step 2: Ensure foreign key is selected for includes

    Using includes(:customer) requires selecting the foreign key customer_id to load customers efficiently.
  3. Step 3: Choose the query that selects needed fields and includes association correctly

    Order.includes(:customer).select(:total_price, :created_at, :customer_id) meets all requirements.
  4. Final Answer:

    Order.includes(:customer).select(:total_price, :created_at, :customer_id) -> Option B
  5. Quick Check:

    Select needed fields + foreign key + includes = A [OK]
Hint: Include foreign keys in select when using includes [OK]
Common Mistakes:
  • Omitting foreign key breaks includes
  • Using joins loads all customer fields unnecessarily
  • Selecting all orders without includes
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard