Database Indexing 101: Why Your Queries Are Slow and How to Fix Them

Database Indexing 101: Why Your Queries Are Slow and How to Fix Them

Arafat Islam
August 30, 2026
4 min read

If there's one technical skill that has the single biggest impact on application performance, it's understanding database indexing. A missing index can turn a query that should take milliseconds into one that takes seconds — and unlike many performance problems, this one usually has a simple, direct fix once you know what to look for.

Database schema diagram on a whiteboard

What an Index Actually Does

Think of a database table without an index like a book with no table of contents or index page — to find any piece of information, you have to read through every single page from the beginning. An index is essentially a sorted lookup structure that lets the database jump directly to relevant rows instead of scanning the entire table.

Without an index on a column you're frequently filtering or joining on, the database performs a "full table scan" — checking every single row to see if it matches your query. On a table with a few hundred rows, this is barely noticeable. On a table with millions of rows, it can mean the difference between a 10-millisecond query and a 10-second one.

When to Add an Index

The general rule: index columns that are frequently used in WHERE clauses, JOIN conditions, and ORDER BY clauses. Common candidates:

  • Foreign key columns (used constantly in joins)
  • Columns used to filter results (status, email, user_id, created_at)
  • Columns used for sorting (especially if combined with LIMIT)

When NOT to Add an Index

Indexing isn't free — it comes with trade-offs. Every index adds overhead to write operations (INSERT, UPDATE, DELETE) since the database has to maintain the index structure alongside the data itself. Over-indexing a write-heavy table can meaningfully slow down writes without providing much benefit if those indexed columns are rarely queried.

Avoid indexing:

  • Columns with very low cardinality (like a boolean flag with only two possible values) — the index often doesn't help much since it can't narrow results significantly.
  • Columns that are rarely used in queries at all.
  • Very large text/blob columns, unless using a specialized full-text index.

Close-up of computer code showing SQL query

How to Actually Find Missing Indexes

Don't guess — use your database's own tools:

  • Enable the slow query log and review it regularly for queries exceeding a reasonable threshold (say, 500ms).
  • Use EXPLAIN (or EXPLAIN ANALYZE) on suspect queries to see the actual execution plan — this will explicitly tell you if a full table scan is happening where an index lookup should be.
  • Many managed database services also provide built-in query performance dashboards that highlight the slowest and most frequent queries automatically.

Composite Indexes for Multi-Column Queries

If you frequently query using multiple columns together (e.g., WHERE user_id = ? AND status = ?), a composite index covering both columns in the right order will outperform two separate single-column indexes for that specific query pattern. Column order in a composite index matters significantly — it should generally match the order of filtering specificity in your most common queries.

The N+1 Query Problem

A related, extremely common performance issue isn't about missing indexes at all — it's about application code that runs one query to get a list of records, then runs a separate query for each record individually to fetch related data (an "N+1" pattern). This can generate hundreds of tiny queries where a single, properly joined query (or an ORM's eager-loading feature) would suffice. Even perfectly indexed tables can't fully compensate for this kind of query pattern inefficiency.

Monitor Query Performance Over Time

Indexing isn't a one-time task. As your data grows and query patterns evolve (new features, changing usage patterns), previously fine queries can become slow, and previously necessary indexes can become dead weight. Periodically reviewing slow query logs — not just when you first launch, but on an ongoing basis — catches this drift before it becomes a real problem.

The Bottom Line

Most "my app got slower as it grew" problems trace back to missing indexes on columns that see heavy query traffic. Learning to read an EXPLAIN output and recognize a full table scan is one of the highest-leverage skills a backend developer can build — it turns vague performance complaints into a specific, fixable diagnosis.