Exact nearest-neighbour search is O(N) per query. At scale you use ANN (approximate nearest neighbour) indexes.
| Index | Idea | Trade-off | | --- | --- | --- | | Flat | brute force | perfect recall, slow above ~100K vectors | | HNSW | navigable small-world graph | fast, high recall, RAM hungry | | IVF(+PQ) | cluster into lists, search a few | compact, needs training, tune `nprobe` | | DiskANN | SSD-resident graph | huge corpora, cheaper RAM |
Key HNSW knobs: `M` (graph degree), `ef_construction` (build quality), `ef_search` (recall vs latency at query time).
sql -- pgvector with HNSW CREATE INDEX ON chunks USING hnsw (embedding vector_cosine_ops) WITH (m = 16, ef_construction = 64); SET hnsw.ef_search = 80; -- raise for better recall
Gotcha: ANN recall degrades silently. Track recall@k against a brute-force baseline on a sample set whenever you change index parameters.