Question presented to candidate:
"Our help-centre search runs SELECT ... WHERE category = 'billing' ORDER BY embedding <=> $1 LIMIT 3 on pgvector with an HNSW index. Sometimes it returns one row or none, even though there are plenty of billing articles. Why, and how would you fix it?"
What a strong answer should cover:
- Why it happens: the ANN index returns its best candidates first (about
hnsw.ef_search, default 40), and theWHEREfilter runs on those candidates afterwards, so a selective filter can leave fewer thanLIMITrows - Exact pre-filtering: a B-tree on
categoryplus an exact distance sort is correct and fast when the filtered set is small; the planner can choose it by itself - Iterative index scans (pgvector 0.8.0):
hnsw.iterative_scan = strict_orderorrelaxed_orderkeeps scanning until enough rows pass, bounded byhnsw.max_scan_tuples - Structural fixes: a partial HNSW index per hot value (
WHERE category = 'billing'), or list partitioning by category with one index per partition - Trade-offs by selectivity, and how to check which plan you got with
EXPLAIN
Clarifying questions expected:
- How many distinct categories, and what fraction of rows does a typical filter keep?
- Is the filter one fixed column, or arbitrary combinations (tenant plus language plus date)?
Code / implementation expected: Yes — show the failing pattern, the exact pre-filter, and the pgvector settings or index that fix it.
Schema used by the examples: