Module 2 / Start with a simple system / Indexes and why queries get slow

Lesson10 minModule 2 · lesson 5 of 7

Indexes and why queries get slow

How a database finds rows without reading them all.

A new app feels fast with a thousand rows. A year later the same page takes seconds, and nothing in the code changed. The cause is almost always the same: the database is reading far more data than the query needs. Understanding why, and the standard fix, is one of the most valuable skills in backend work.

Suppose the orders table has 10 million rows and you ask for the orders of customer 77. With no help, the database does a full table scan: it reads every row and checks the customer. If each row is about 100 bytes, that is roughly 1 GB read to return a handful of rows. An index is a separate sorted structure, usually a B-tree, that maps a column's values to where the rows live. Looking up a value in a sorted tree takes only a few steps (around 3 to 4 levels for 10 million rows), then a direct jump to the rows.

Query: orders for customer 77Full scan of 10M rowsIndex on customer_idMatching rowsno index(slow)with index(fast)readeverythingjump to ~20rows
The same question, two paths.
-- slow without an index: scans the whole table
SELECT * FROM orders WHERE customer_id = 77 ORDER BY created_at DESC LIMIT 20;

-- fix: one composite index serves both the filter and the sort
CREATE INDEX idx_orders_customer_time
  ON orders (customer_id, created_at DESC);

-- check what the database really does
EXPLAIN SELECT * FROM orders WHERE customer_id = 77;
Use EXPLAIN to see whether a query scans or uses an index.

Indexes are not free. Every index takes disk space, and every insert or update must also update each index, so writes get slower. An index on a column that is rarely used in queries is pure cost. Order matters in a composite index: one on (customer_id, created_at) helps queries filtering on customer_id, or on both, but not queries that filter only on created_at. Indexes also help little when a column has very few distinct values, like a boolean.

Finding and fixing a slow query

Step 1 of 5

Notice the symptom

A page or endpoint gets slower as data grows, though the load is the same.

Question 1

Why does an unindexed lookup in a 10-million-row table get slower as the table grows?

Question 2

What is the main cost of adding many indexes?

Your turn

The query SELECT * FROM orders WHERE restaurant_id = 5 AND status = 'open' is slow. Propose an index and say what you would check first.

Stuck? Think about both filter columns, and the tool that shows the plan.

What to remember

  1. Without an index the database scans every row; cost grows with table size.

  2. An index is a sorted structure that jumps straight to matching rows.

  3. Indexes speed reads but slow writes and use space.

  4. Composite index order matters.

  5. Use EXPLAIN to find and verify fixes.