TRT
Sign in
SystemInternalsstorage

Trace: How a B-Tree Index Narrows a Database Search

A database index is an auxiliary structure that helps find rows without scanning every table page. A B-tree keeps keys in sorted order across pages and uses separator keys to direct a search from the root toward a leaf. The index is valuable when its lookup cost is lower than the work it avoids.

The Runtime Theory Team8 min read05 steps

layer stack

System

HWHardware
KKernel
RTRuntime
APPApplication
SYSSystem
CLIClient
NETNetwork
TLSCrypto
SRVServer

trace spine

  1. 01 Compare key at an index page
  2. 02 Choose the child page
  3. 03 Reach the matching leaf range
  4. 04 Fetch qualifying table rows
  5. 05 Maintain index pages on writes

This trace follows the actual state transitions behind the companion How a B-Tree Index Narrows a Database Search. Each step below names its concrete inputs; values illustrate the mechanism and vary across implementations.

Step 1: Compare key at an index page

A database index is an auxiliary structure that helps find rows without scanning every table page. A B-tree keeps keys in sorted order across pages and uses separator keys to direct a search from the root toward a leaf. The index is valuable when its lookup cost is lower than the work it avoids.

Step 2: Choose the child page

For a query filtering by customer_id and ordering by created_at, a composite index beginning with customer_id may narrow to one customer’s key range and then return rows in order. If the query selects columns present in the index, some engines may avoid visiting table pages for each result.

Step 3: Reach the matching leaf range

A B-tree search repeatedly narrows the key range using separator values; whether the index helps overall depends on how many table pages the query still needs.

Checkpoint: A B-tree search repeatedly narrows the key range using separator values; whether the index helps overall depends on how many table pages the query still needs. Confirm this state before advancing to Fetch qualifying table rows.

Step 4: Fetch qualifying table rows

Indexes consume storage and add work to inserts, deletes, and updates. A low-selectivity column may not justify an index by itself, and a query planner can prefer a sequential scan when many rows qualify. Composite index column order changes which predicates can use its leading range efficiently.

Step 5: Maintain index pages on writes

Given an index on (tenant_id, created_at), compare queries filtering by tenant_id alone and created_at alone. Explain what information the index ordering makes directly available.

The trace is done when this check holds: Given an index on (tenant_id, created_at), compare queries filtering by tenant_id alone and created_at alone. Compare the outcome against the companion article before making a performance claim.

Hardware, runtime, and observability notes

When tracing Trace: How a B-Tree Index Narrows a Database Search in a live production environment (subsystem: storage, primary layer: system), keep the following step-level cost model and diagnostic checklist in mind:

  • Step 1 (system): Compare key at an index page — verifies state invariants before advancing the execution pointer.
  • Step 2 (system): Choose the child page — verifies state invariants before advancing the execution pointer.
  • Step 3 (system): Reach the matching leaf range — verifies state invariants before advancing the execution pointer.
  • Step 4 (system): Fetch qualifying table rows — verifies state invariants before advancing the execution pointer.
  • Step 5 (system): Maintain index pages on writes — verifies state invariants before advancing the execution pointer.

Every transition across the system boundary carries both a direct CPU/memory cost (cache-line fills, descriptor lookups, lock acquisitions, or context switches) and a tail-latency queueing risk under contention. To verify this trace on your own service, capture latency histograms and hardware/kernel counters across each step boundary, compare cold-cache versus warm-cache execution paths, and confirm that error or timeout branches release all acquired descriptors, locks, and buffers cleanly.

Not started

Sign in to save your learning progress.

Sign in to save