Thuta Learning
IntermediateData & Databasesbeginner

Indexes and Their Tradeoffs

What you'll walk away with

  • Explain the core ideas behind Indexes and Their Tradeoffs
  • Read the diagram/table and identify the shape of the data model, schema, or architecture
  • Explain how this concept or system choice applies to a real project

Build the mental model

An index helps the database find rows quickly without scanning the whole table - like a book's index, jumping straight to the right page.

It's an Analogy, Not an Identical Mechanism

A database index is a separate structure the engine maintains internally, and it differs from a printed book's page list in real, mechanical ways.

Indexes are a tradeoff: they speed up reads, but cost extra storage, and every write has to update the index too, making writes slower.

  • columns frequently used in WHERE filters
  • columns used in joins
  • columns used in ORDER BY sorting
  • columns needing fast unique lookups (e.g. email)
  • don't index every column

A unique index enforces that no two rows share a value while speeding up lookups. A composite index covers multiple columns, and column order changes which queries it helps.

The N+1 query problem: fetching 100 posts then running 100 separate author queries is often far slower than one join fetching everything together. The SQL and PostgreSQL tutorials cover index syntax and EXPLAIN hands-on.

Index
A separate data structure the database maintains to find rows quickly based on one or more columns, without scanning the whole table.
N+1 Query Problem
A pattern where fetching a list (100 posts) is followed by one separate query per item for related data (author), making it far slower than a single join or batch.
text
INDEX LOOKUP VS FULL SCAN, AND N+1
----------------------------------
WITHOUT INDEX (linear scan)
row1 -> row2 -> row3 -> ... -> row9999 -> MATCH
checks potentially every row until found

WITH INDEX (direct lookup)
index[key] -> MATCH
one direct jump to the row, like a book's index

N+1 PROBLEM
1 query:     SELECT * FROM posts;          (100 rows)
100 queries: SELECT * FROM authors WHERE id=? (x100)
BETTER: 1 query with a JOIN, or 1 batched IN (...)

Connect it to a real scenario

Add an index once you notice a slow query repeatedly filtering, joining, or sorting on the same column - not preemptively on every column.

Tools like PostgreSQL's EXPLAIN exist exactly to inspect which indexes exist and how the query planner uses them.

Watch for N+1 patterns in loops - a query running once per item is usually a sign to batch into a single join or query instead.

Before adding an index, ask whether the write overhead is worth it for that table's read/write ratio. The runnable example below shows the search difference with and without an index.

Try the working example

javascript
function linearSearch(rows, field, value) {
  let comparisons = 0;
  let found = null;
  for (const r of rows) {
    comparisons++;
    if (r[field] === value) {
      found = r;
      break;
    }
  }
  return { found, comparisons };
}

function buildIndex(rows, field) {
  const map = new Map();
  for (const r of rows) map.set(r[field], r);
  return map;
}

function indexedSearch(index, value) {
  return { found: index.get(value) || null, comparisons: 1 };
}

const bigTable = [];
for (let i = 1; i <= 5000; i++) {
  bigTable.push({ id: i, email: `user${i}@example.com` });
}
const target = "user4999@example.com";

const withoutIndex = linearSearch(bigTable, "email", target);
const emailIndex = buildIndex(bigTable, "email");
const withIndex = indexedSearch(emailIndex, target);

console.log("Without index comparisons:", withoutIndex.comparisons);
console.log("With index comparisons:", withIndex.comparisons);
You should see
Without index comparisons: 4999
With index comparisons: 1

Searching for the 4999th row out of 5000 takes 4999 comparisons with a linear scan, but only 1 lookup using a Map-based index.

5-minute try-it

Re-run linearSearch/indexedSearch against 50,000 rows and note the comparison-count difference. Observe how the gap changes as table size grows.

One important caution

Indexing every column "to be safe" without accounting for the write-performance cost

Not recognizing a loop running one query per item as the N+1 problem

Wikipedia: Database indexHow Databases Work

Easy traps

  • Indexing every column "to be safe" without accounting for the write-performance cost
  • Not recognizing a loop running one query per item as the N+1 problem
  • This course teaches database concepts and the product landscape at a framework-neutral level -- for hands-on SQL syntax or PostgreSQL/MongoDB/Redis depth, continue to the SQL, PostgreSQL, MongoDB, or Redis tutorials.

Exercise

Re-run linearSearch/indexedSearch against 50,000 rows and note the comparison-count difference. Observe how the gap changes as table size grows.

You'll know it worked when: Without index comparisons: 4999 With index comparisons: 1 Searching for the 4999th row out of 5000 takes 4999 comparisons with a linear scan, but only 1 lookup using a Map-based index.

Indexes and Their Tradeoffs | Thuta Learning