ClickHouse / ClickHouse/ClickHouse
Distributed plan (`make_distributed_plan`) returns an incorrect top-N for vector search queries
- Dominant language
- C++
- Stars
- 49.9k
- Forks
- 9k
- Avg merge
- 21h 32m
- Merged PRs (30d)
- 515
Description
🕵 Reproduced on master (2026-08-12, commit `24a4d5c6890a`-era) on a single server.
A vector search query (`ORDER BY L2Distance(...) LIMIT n` with a `vector_similarity` index) returns the wrong rows when executed through the experimental distributed plan, in both rescoring modes:
```sql
CREATE TABLE tab (id Int32, vec Array(Float32), INDEX idx vec TYPE vector_similarity('hnsw', 'L2Distance', 2) GRANULARITY 100000000) ENGINE = MergeTree ORDER BY id SETTINGS index_granularity = 2;
INSERT INTO tab VALUES (0, [1.0, 0.0]), (1, [1.1, 0.0]), (2, [1.2, 0.0]), (3, [1.3, 0.0]), (4, [1.4, 0.0]), (5, [0.0, 2.0]), (6, [0.0, 2.1]), (7, [0.0, 2.2]), (8, [0.0, 2.3]), (9, [0.0, 2.4]);
WITH [0., 2.] AS reference_vec
SELECT id FROM tab ORDER BY L2Distance(vec, reference_vec) ASC LIMIT 3
SETTINGS make_distributed_plan = 1, distributed_plan_execute_locally = 1,
distributed_plan_default_reader_bucket_count = 3,
distributed_plan_default_shuffle_join_bucket_count = 3,
distributed_plan_max_rows_to_broadcast = 0, enable_parallel_replicas = 0;
```
- Correct result (no distributed plan, or `use_skip_indexes = 0` with distributed plan): `5, 6, 7` (distances 0, 0.1, 0.2).
- With the distributed plan and the vector index in use: `4, 5, 6` — row `4` has distance ~2.44 and must not beat row `7` (0.2). The result is the same with `vector_search_with_rescoring = 0` and with the default rescoring mode, so the problem is in how the distributed read buckets combine with the vector-index candidate hints, not in the no-rescoring plan rewrite.
Note: with `vector_search_with_rescoring = 0` the same query used to fail earlier at plan build time with a logical error ("Cannot add step `Limit` to `QueryPlan` because it has incompatible header with root step `Sorting`") — that separate defect is fixed by the PR linked below, which also carries a regression test that asserts only the row count because of this wrong-result bug.
Related: https://github.com/ClickHouse/ClickHouse/pull/42701
Contributor guide
Assessment
This issue has not been assessed yet.