What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Add a database index in Rails when a recurring query or an integrity rule gives you a specific reason—not simply because a column appears in a query. Indexes can speed up row lookups, but they also add work and storage costs to the database. Use Rails migrations to define the index, then inspect the database’s query plan and workload to see whether it helps.
What a database index does—and what it costs
An index is a data structure the database can use to locate rows without examining the whole table in the same way as an unindexed lookup. PostgreSQL’s documentation sums up the trade-off: “An index allows the database server to find and retrieve specific rows much faster than it could do without an index. But indexes also add overhead to the database system as a whole, so they should be used sensibly.” PostgreSQL 18: Indexes
The benefit is faster retrieval for queries that can use the index. The cost is additional work for the database system, including maintaining indexes as data changes. There is no universal speedup figure: the result depends on the query, data, database engine, and workload.
When should you add an index in Rails?
Start with a recurring query or a database integrity requirement. Look at the query’s filters and sort order, then examine the plan the database chooses. An index is a candidate to test, not a guarantee of improvement: the optimizer may choose another plan, and a faster read can come with costs elsewhere in the workload.
#1 Best Overall
- Frequent lookup or filtering: Consider an index on the columns used to find the relevant rows.
- Filtering and sorting together: Consider a composite index only when its column order fits the actual query patterns. Column order is meaningful; a composite index is not a set of interchangeable single-column indexes.
- Uniqueness: Use a unique database index when the database must prevent duplicate values.
- Search or specialized access: Choose an index method that matches the search and is supported by your database adapter.
Do not index every queried column by default. Check the plans for representative queries and consider the broader workload, including writes and index maintenance. PostgreSQL 18 index guidance and the Rails 8.1 Active Record Query Interface guide explain the trade-off and plan inspection.
How to add an index in a Rails migration
Rails migrations provide add_index for a single column or an array of columns. The following examples use the Rails 8.1 migration class syntax; check the syntax and option support for your app’s Rails version and database adapter.
Rank #2
Single-column and composite indexes
class AddIndexesToOrders < ActiveRecord::Migration[8.1]
def change
add_index :orders, :customer_id
add_index :orders, [:customer_id, :created_at]
end
end
The single-column index is a candidate for queries that filter on customer_id. The composite example may fit queries that filter by customer and use creation time, but its usefulness depends on the predicates and ordering in the actual workload. Verify the plan rather than assuming either index will be used.
Enforcing uniqueness
add_index :users, :email, unique: true
A unique index is a database-level integrity rule as well as an access path. Application validations alone cannot guarantee uniqueness in every circumstance. Before adding one, check existing rows for duplicates and coordinate the constraint with the application’s validation and error-handling behavior. Rails’ migration guidance discusses database-level unique indexes and foreign keys as stronger integrity enforcement. Rails Active Record Migrations guide
Rank #3
PostgreSQL concurrent creation
For PostgreSQL, Rails supports algorithm: :concurrently when creating an index. Concurrent index creation cannot run inside a transaction, so disable the migration’s DDL transaction:
class AddIndexToOrdersOnCustomerId < ActiveRecord::Migration[8.1]
disable_ddl_transaction!
def change
add_index :orders, :customer_id, algorithm: :concurrently
end
end
This option is PostgreSQL-specific, not a portable instruction for every Rails database. Check the behavior for your Rails and adapter versions and account for the migration’s production deployment implications. Rails documents the algorithm option in its Rails 8.0 add_index API and the transaction restriction in its migration guidance.
Rank #4
How to check whether the database uses the index
Active Record’s .explain shows the database plan for a relation. Inspect a query shaped like the one your application actually runs:
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsOrder.where(customer_id: 42).order(:created_at).explain
For PostgreSQL, Rails also documents analysis options such as:
Best Value
Order.where(customer_id: 42).order(:created_at).explain(:analyze, :buffers)
Options such as :analyze execute the query to gather measurements; choose a suitable query and environment before using them. Rails documents analysis support and engine-specific differences for PostgreSQL, MySQL, and MariaDB in its Active Record Query Interface guide and Active Record and PostgreSQL guide.
A plan is evidence about that query and the data available when the plan was produced. It does not prove that the index will always be selected or improve the complete workload. Compare representative query behavior and consider write activity and index maintenance alongside read performance.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Which index option fits the query?
Choose the index shape from the access pattern, integrity need, database support, and deployment conditions. Rails exposes options for several index features, but availability and behavior vary by adapter.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstall- Single-column index: A straightforward candidate for a recurring lookup or filter on one column.
- Composite index: A candidate when queries use multiple columns together. Match the column order to real predicates and ordering; validate with a plan.
- Unique index: Appropriate when the database must enforce that indexed values are unique.
- Partial index: Rails documents support for PostgreSQL and SQLite. It indexes rows matching a condition, so confirm that the target query and adapter support align.
- Included columns: Rails documents included columns for PostgreSQL only. PostgreSQL can make included values available to index-only scans without using those columns as search keys.
- Index method: The available methods depend on the adapter. PostgreSQL’s guide, for example, describes GIN-based examples for full-text search; do not treat PostgreSQL-specific methods as portable Rails options.
Rails documents the add_index options and adapter qualifications in its Rails 8.0 API reference. PostgreSQL’s Rails and PostgreSQL guide describes PostgreSQL-specific index features.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

