Start studying
Module 8 · Embeddings & Search Module contents
Module 8  ·  Card 5 / 17beginner

Nearest-Neighbour Search

Nearest-neighbour search finds the vectors closest to a query vector.

Exact search compares against every vector and is perfectly accurate.

That becomes far too slow once you have millions of vectors.

Approximate nearest neighbour trades a little recall for enormous speed.

In practice ANN returns almost the same results thousands of times faster.

Learn in depth ↓
Module 08 · Embeddings & Search · 17 concepts
In depth  /  15 lines

Nearest-Neighbour Search, in more detail

Nearest-neighbour search is the operation at the heart of vector retrieval.

Given a query vector, find the stored vectors closest to it.

Exact search compares against every vector and is perfectly accurate.

With a thousand vectors that is instant, and with fifty million it is hopeless.

The cost grows linearly with the corpus and every query pays it in full.

Approximate nearest neighbour gives up the guarantee to buy speed.

It searches a structure built in advance rather than scanning everything.

Recall measures what it costs you, being the fraction of true neighbours returned.

Typical settings reach 95 to 99 per cent recall while being hundreds of times faster.

Missing one result in twenty rarely matters when a reranker sees the rest.

HNSW builds a navigable graph and is the most common approach.

IVF splits the space into cells and searches only the nearest few.

Product quantisation compresses vectors so more of them fit in memory.

Each has a knob trading recall against speed and memory, and none of the three is free.

Exact search is still right for small collections, and premature indexing is a common waste.

Want the full technical article? Wikipedia ↗
Deep dive

What is underneath Nearest-Neighbour Search

The exact answer, and what it costs

NN(q)=arg⁡min⁡i∈{1…n}d(q,xi)\mathrm{NN}(\mathbf{q}) = \arg\min_{i \in \{1 \dots n\}} d(\mathbf{q}, \mathbf{x}_i)

A brute-force scan computes the distance to every stored vector and keeps the smallest, which is exact by construction.

O(nd)O(n d)

With a million vectors of 768 dimensions that is about 1.5 billion multiply-adds per query, or a few hundred milliseconds on a CPU core.

O(nd+nlog⁡k)O(n d + n \log k)

Adding the selection of the top kk changes nothing important. The scan dominates, and it grows linearly with the corpus forever.

A flat index is therefore the right answer up to roughly a hundred thousand vectors, and the wrong one above a few million.

Why the classical structures fail here

k-d tree:O(log⁡n) for d≲20\text{k-d tree} : O(\log n) \text{ for } d \lesssim 20

Space-partitioning trees work by pruning branches that cannot contain a closer point, and pruning depends on distances being well separated.

dmax⁡−dmin⁡dmin⁡→0 as d→∞\frac{d_{\max} - d_{\min}}{d_{\min}} \to 0 \text{ as } d \to \infty

In high dimensions they are not, so almost no branch can be excluded and the tree degrades to a full scan with overhead on top.

Embeddings live in hundreds of dimensions, which is exactly the regime where exact indexing stops being possible.

Approximate search, and the trade it makes

recall@k=∣returned∩true top k∣k\text{recall@}k = \frac{|\text{returned} \cap \text{true top } k|}{k}

An approximate index gives up exactness and reports how much: recall of 0.95 means 19 of the true top 20 were found.

speedup×100 for recall 0.95\text{speedup} \times 100 \text{ for recall } 0.95

That is the bargain. Two orders of magnitude faster for one missed result in twenty, and for retrieval the twentieth result rarely changes the answer.

The three families divide by what they give up. Trees and graphs restrict what is visited, hashing restricts what is compared, and quantisation shrinks what is stored.

One search, in order

  1. Normalise the query the same way the stored vectors were normalised.
  2. Use the index to select a small candidate set, orders of magnitude smaller than nn.
  3. Compute exact distances on those candidates only.
  4. Keep the top kk by that exact score.
  5. Optionally rescore the survivors with a stronger model.

Step three is why quantised indexes still work.

The compressed vectors choose the candidates and the full vectors decide the order, so the compression error affects recall rather than ranking.

Choosing an index

Below 10510^5 vectors, a flat exact index needs no tuning.

From 10510^5 to 10710^7, HNSW is the fastest and the most memory-hungry.

Above 10710^7, IVF with product quantisation suits data on disk.

Those thresholds move with hardware and with how much memory you are willing to buy, and the ordering between them does not.

The first question to ask of any vector database is which of these it is running underneath, because every tuning parameter it exposes belongs to one of them.

Test yourself

One question on this card. Every option explains itself once you pick, right or wrong.

Question 1
Why is approximate nearest neighbour search used instead of exact search?
Embeddings & Search

17 concepts in this module, then a graded test with every answer explained.

Study this module →
↑↓ move↵ openesc close