CONCEPT SHEET · Concepts

Database Indexing

One-liner: An index is a secondary structure that trades write cost and space for O(log N) lookups instead of full scans.

ArticleConcepts© Arthur Bernier Jr524 words1 code block

Say this#

How it works#

B-tree lookup: root → internal pages → leaf; leaf holds key + row pointer (TID). Range scan walks leaf siblings.

TEXT
B-tree:  [ 50 | 100 ]            fan-out ~hundreds; 3-4 levels covers billions of rows        /     |      \   [1..49] [50..99] [100..]  -> leaf -> heap row LSM:  write -> WAL + memtable (sorted in RAM) --flush--> SSTable L0 --compact--> L1 ... Ln      read  -> memtable -> Bloom filters -> newest SSTable first

Composite index (user_id, created_at): WHERE user_id = ? ORDER BY created_at DESC LIMIT 20 is a single index range walk. WHERE created_at > ? alone cannot use it.

Trade-offs#

ChoiceProCon
B-treeRange + equality + ordering, matureRandom-write heavy; page splits; write amplification
HashFastest equalityNo range, no ordering
LSM-treeSequential writes, high ingest, good compressionRead amplification, compaction CPU/IO bursts, space amplification
More indexesFaster readsSlower writes, more storage, planner confusion
Covering indexAvoids heap lookupsWider index, more write cost
Clustered PK (InnoDB)PK range scans are sequential IORandom UUID PKs fragment pages; use sequential IDs/UUIDv7

Numbers#

  • B-tree height 3-4 for ~10^9 rows with 8 KB pages; lookup is 3-4 page reads, mostly cached.
  • Postgres default page 8 KB; MySQL InnoDB 16 KB.
  • Rule of thumb: a full table scan beats an index when selecting more than ~5-10% of rows.
  • Each additional index commonly costs 10-30% write throughput on insert-heavy tables (order of magnitude).

In the interview#

See also