# Week 9 - The Case for Learned Index Structures

Last edited: 2026-07-27

Paper: The Case for Learned Index Structures — Kraska, Beutel, Chi, Dean & Polyzotis, SIGMOD 2018.

The core claim: indexes are models. A B-Tree maps a key to a position in a sorted array — that is a regression model. A hash map maps a key to an array slot — that is also a model. A Bloom filter predicts whether a key exists — that is a binary classifier. If indexes are models, they can be replaced by learned models that exploit the actual data distribution to be faster and smaller.

# The Key Insight: Indexes as CDFs

For a range index over a sorted array, the position of a key $k$ among $N$ records is:

$$p = F(\text{Key}) \times N$$

where $F(\text{Key})$ is the cumulative distribution function (CDF) of the data — the probability of observing a key $\leq$ Key. A B-Tree implicitly learns this CDF by recursively partitioning the key space. Any regression model that approximates the CDF can serve as a range index.

Note

If keys are consecutive integers from 1 to 100M, a simple linear model $F(k) = k / 100M$ would give exact positions in $O(1)$ with zero memory overhead. A B-Tree would need $O(\log N)$ comparisons. Knowing the data distribution perfectly collapses the index to a constant-time lookup.

This is what makes the idea compelling: most real-world data has learnable structure (web-server log timestamps, geographic coordinates, etc.), and a model that captures that structure can outperform a general-purpose B-Tree.

# Why a Single Neural Net Fails

A naïve approach — train one neural net on all 200M records — achieves ~1250 lookups/second with TensorFlow, versus ~3M lookups/second for a B-Tree. Three problems:

  1. TensorFlow invocation overhead: designed for large model batches, not single-record inference. ~80,000 ns to call the model vs ~300 ns for a B-Tree traversal.

  2. Last-mile accuracy: a single model can learn the global CDF shape but struggles to get within 100 positions for individual records. B-Trees are excellent at this — each node recursively partitions the space with if-statements, which are very fast.

  3. Cache efficiency: B-Trees keep top nodes in cache and access others on demand. Neural nets must load all weights for every inference.

# The Recursive Model Index (RMI)

The solution is a hierarchy of models (mixture of experts), where each stage picks the model for the next stage:

Stage 1:  [Model 1.1]                     ← learns global CDF shape
Stage 2:  [Model 2.1] [Model 2.2] [Model 2.3] ...
Stage 3:  [Model 3.1] [Model 3.2] [Model 3.3] [Model 3.4] ...
                          ↓
                       Position

Each model $f_\ell^{(k)}$ at stage $\ell$ is trained with loss:

$$L_\ell = \sum_{(x,y)} \left( f_\ell^{\lfloor M_\ell \cdot f_{\ell-1}(x)/N \rfloor}(x) - y \right)^2$$

The output of a model at stage $\ell$ is used directly to select the model index at stage $\ell+1$ — no search between stages, just a single multiplication.

Benefits:

  • Separates model size from execution cost: a top-level NN can capture complex global patterns cheaply; thousands of tiny linear models handle the “last mile”.
  • Effectively partitions the key space, like a B-Tree, but the partition boundaries adapt to data density.
  • Hybrid fallback: if any last-stage model has max absolute error above a threshold, replace it with a B-Tree. This bounds worst-case performance to that of a B-Tree.

Training is end-to-end stage-by-stage: train stage 1, use its output to route records to stage 2 models, train each stage 2 model on its subset, and so on.

# Search Strategies

Since the model predicts a position $\hat{p}$ with a stored min-error and max-error, the actual key must be in $[\hat{p} - \text{min\_err}, \hat{p} + \text{max\_err}]$.

  • Model-biased binary search: binary search starting from the predicted middle $\hat{p}$ rather than the true middle of the range.

  • Biased quaternary search: prefetch three points ($\hat{p} - \sigma$, $\hat{p}$, $\hat{p} + \sigma$) simultaneously, exploiting hardware prefetching to hide memory latency for data not in cache.

# Point Index: Learned Hash Functions

A hash function $h(k)$ maps keys to slots in a hash table. A learned hash function uses the CDF:

$$h(K) = F(K) \times M$$

where $M$ is the number of slots. If $F$ perfectly models the key distribution, keys are spread uniformly and zero conflicts occur. Traditional random hash functions achieve ~33% conflict rate by the birthday paradox regardless of data structure.

The learned hash function is orthogonal to the hash-map architecture (chaining, cuckoo hashing, etc.) — it just produces better slot assignments. Results on three datasets: conflict reduction of 26–77% over random hashing, with model execution time of ~25–40 ns (same as a B-Tree traversal node).

# Existence Index: Learned Bloom Filters

A Bloom filter is a binary classifier: given key $x$, predict whether $x \in \mathcal{K}$ (key set). Traditional Bloom filters have no false negatives but have tunable false positive rates (FPR), using $O(n \log(1/\text{FPR}))$ bits.

Learned Bloom filter (Figure 9c):

  1. Train a model $f(x)$ to classify keys vs non-keys (e.g., a character-level RNN for URL keys).

  2. Choose threshold $\tau$: if $f(x) \geq \tau$, predict key exists.

  3. The model will have some false negatives ($\mathcal{K}_\tau^- = \{x \in \mathcal{K} \mid f(x) < \tau\}$).

  4. Add a small overflow Bloom filter covering only $\mathcal{K}_\tau^-$ to eliminate false negatives.

The overall FPR is $\text{FPR}_O = \text{FPR}_\tau + (1 - \text{FPR}_\tau) \cdot \text{FPR}_B$, where $\text{FPR}_B$ is the overflow Bloom filter FPR. Setting $\text{FPR}_B = p^*/2$ achieves target FPR $p^*$.

The model is smaller than a full Bloom filter when it can accurately separate keys from non-keys. Result on 1.7M phishing URLs: 36% memory reduction at 1% FPR using a GRU character-level RNN.

# Performance Results

Range index (Figure 4), 200M integer records, compared to a production B-Tree (page size 128 as baseline):

IndexSizeLookupvs B-Tree
B-Tree (page 128)12.46 MB263 ns
RMI 2-stage, 10k models0.15 MB152 ns0.06× size, 1.73× faster
RMI 2-stage, 100k models1.53 MB121 ns0.12× size, 2.17× faster

The learned index is up to 1.5–3× faster and 4× smaller than the B-Tree. Most of the performance gain comes from the second-stage model size — 100k second-stage models means the first stage can make a much larger precision jump than a single B-Tree node.

String data (Figure 6): learned indexes provide smaller speedups over B-Trees for strings due to higher model execution cost. Hybrid indexes (replacing bad models with B-Trees) help.

Lookup table comparison (Figure 5): the best alternative baseline is a fixed-size B-Tree with interpolation search at 280 ns and 1.5 MB. The learned index achieves 105 ns at 1.5 MB — 2.7× faster at the same size.

# Limitations and Open Problems

The paper is explicit that this is an exploratory result targeting read-only, in-memory, analytical workloads:

  • Inserts: appends to a sorted array are $O(1)$ if the distribution generalises; inserts in the middle require data movement. A delta-index (buffer + periodic merge) is proposed as a near-term solution.

  • Distribution shift: if data distribution changes, models need re-training — B-Trees self-balance automatically.

  • Write-heavy workloads: not evaluated; open research question.

  • Multi-dimensional indexes: extending to 2D+ (e.g., R-trees) is identified as the most exciting future direction.

# Key Takeaways

Index typeTraditionalLearned replacementMechanism
Range (B-Tree)Recursive key partitioningRMI: hierarchy of CDF regressors$p = F(\text{Key}) \times N$
Point (Hash map)Random hash functionLearned CDF scaled to table sizeFewer conflicts
Existence (Bloom filter)Bit array + $k$ hash functionsBinary classifier + overflow Bloom filterSmaller at same FPR

The unifying insight: all three index types can be seen as approximating the data distribution, and machine learning gives a systematic way to build that approximation automatically from the data.