Vector Search: Distance, ANN, and ENN
Implement vector search with VECTOR_DISTANCE and VECTOR_SEARCH β understand approximate vs exact nearest neighbours and evaluate search performance.
Finding the closest vectors
Imagine finding the nearest coffee shop.
Exact nearest neighbour (ENN) checks every single coffee shop in the city and guarantees the absolute closest one. Accurate, but slow if there are 100,000 shops. Approximate nearest neighbour (ANN) uses a smart shortcut β it checks only nearby neighbourhoods and finds a coffee shop that is very likely the closest (99%+ accuracy) but in a fraction of the time.
For most applications, ANN is the right choice β it is dramatically faster and almost always finds the correct answer.
ANN vs ENN
| Feature | ANN (Approximate) | ENN (Exact) |
|---|---|---|
| Accuracy | ~95-99% recall (may miss a few results) | 100% β guaranteed correct top-K |
| Speed | Milliseconds (uses vector index) | Seconds to minutes (full scan) |
| Requires index? | Yes β DiskANN vector index | No β works without index |
| Scales to | Billions of vectors | Thousands to low millions |
| Use when | Production search, real-time queries | Small datasets, validation, accuracy-critical analysis |
Implementing vector search
VECTOR_SEARCH function
-- ANN search: find top 10 similar products (uses vector index)
SELECT vs.ProductId, vs.Name, vs.distance
FROM VECTOR_SEARCH(
Products, -- table
'DescriptionEmbedding', -- vector column
@queryVector, -- query vector
10, -- top K results
'cosine' -- distance metric
) AS vs;
-- ENN search: exact nearest neighbours (brute force)
SELECT TOP 10 ProductId, Name,
VECTOR_DISTANCE('cosine', DescriptionEmbedding, @queryVector) AS Distance
FROM Products
ORDER BY Distance ASC;
Combining vector search with filters
-- Search within a specific category (pre-filter)
SELECT vs.ProductId, vs.Name, vs.distance
FROM VECTOR_SEARCH(
(SELECT * FROM Products WHERE CategoryId = 5), -- pre-filtered
'DescriptionEmbedding',
@queryVector,
10,
'cosine'
) AS vs;
-- Post-filter: search first, then filter
SELECT * FROM (
SELECT vs.ProductId, vs.Name, vs.distance, p.Price
FROM VECTOR_SEARCH(Products, 'DescriptionEmbedding', @queryVector, 50, 'cosine') vs
INNER JOIN Products p ON vs.ProductId = p.ProductId
) filtered
WHERE Price < 100
ORDER BY distance ASC;
Exam tip: Pre-filter vs post-filter
Pre-filtering applies WHERE clauses BEFORE vector search β the ANN index searches only within the filtered subset. More accurate but may not use the vector index efficiently if the subset is small.
Post-filtering runs vector search on the full dataset and filters results afterward. Simpler and uses the index fully, but you may need to request more results (top 50) to get enough after filtering (top 10).
The exam may present a scenario where vector search returns irrelevant results from the wrong category β the fix is adding a pre-filter or post-filter.
Evaluating search performance
Key metrics
| Metric | What It Measures | Target |
|---|---|---|
| Recall@K | Proportion of true top-K results found by ANN | greater than 95% |
| Latency (p50/p95) | Query response time | less than 100ms for production |
| Queries per second | Throughput under load | Depends on workload |
| Index build time | Time to create/rebuild vector index | Hours for millions of vectors |
Testing recall
-- Compare ANN results with ENN (ground truth) for a sample
-- 1. Get exact top 10 (ENN)
SELECT TOP 10 ProductId, VECTOR_DISTANCE('cosine', DescriptionEmbedding, @queryVector) AS Distance
INTO #ENN_Results FROM Products ORDER BY Distance ASC;
-- 2. Get approximate top 10 (ANN)
SELECT ProductId, distance INTO #ANN_Results
FROM VECTOR_SEARCH(Products, 'DescriptionEmbedding', @queryVector, 10, 'cosine');
-- 3. Calculate recall
SELECT CAST(COUNT(*) AS FLOAT) / 10 AS Recall
FROM #ANN_Results a
WHERE EXISTS (SELECT 1 FROM #ENN_Results e WHERE e.ProductId = a.ProductId);
Scenario: Leo tests search quality at SearchWave
Leo runs a recall test on SearchWaveβs product search. For 100 random queries, he compares ANN results (top 20) with ENN ground truth (top 20). Average recall is 97% β meaning ANN finds 97 out of 100 of the exact nearest neighbours. The 3 missed results are very close in distance (marginal differences). For an e-commerce search, this is excellent β users would not notice the difference.
He also measures p95 latency: ANN = 23ms, ENN = 4,200ms. ANN is 180x faster. The decision is clear: ANN for production.
Priya at Vault Bank has 10 million embeddings and needs sub-50ms search latency. She runs a recall test and gets 98% recall with ANN. The security team asks: 'Can you guarantee you always find the most similar record?' What should Priya explain?
π¬ Video coming soon
Next up: Hybrid Search and Reciprocal Rank Fusion β combine keyword and vector search for the best of both worlds.