Inconsistent results between tikv and tiflash when performing vector search
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 1k
- Forks
- 423
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 24
Description
Bug Report
Currently, vector index is only built in tiflash. When we perform vector search, if the plan chooses to follow the tiflash path, tidb will directly use the distance calculated in tiflash for sorting. If the plan chooses to follow the tikv path, after tikv calculates the distance, tidb will still perform another distance calculation and sort based on this result. At this time, since tiflash calculates the distance by calling the optimized calculation of the SIMD library, the direct calculation method of tidb will produce different results, so the tikv and tiflash paths will produce different results.
mysql> explain select /*+ read_from_storage(tikv[t1]) */ id from t1 order by vec_cosine_distance(vec, '[1,1,1]') limit 10;
+--------------------------------+---------+-----------+---------------+------------------------------------------------------------------------------+
| id | estRows | task | access object | operator info |
+--------------------------------+---------+-----------+---------------+------------------------------------------------------------------------------+
| Projection_15 | 10.00 | root | | test.t1.id |
| └─TopN_8 | 10.00 | root | | Column#4, offset:0, count:10 |
| └─Projection_16 | 10.00 | root | | test.t1.id, test.t1.vec, vec_cosine_distance(test.t1.vec, [1,1,1])->Column#4 |
| └─TableReader_14 | 10.00 | root | | data:TopN_13 |
| └─TopN_13 | 10.00 | cop[tikv] | | vec_cosine_distance(test.t1.vec, [1,1,1]), offset:0, count:10 |
| └─TableFullScan_12 | 100.00 | cop[tikv] | table:t1 | keep order:false, stats:pseudo |
+--------------------------------+---------+-----------+---------------+------------------------------------------------------------------------------+
6 rows in set (0.01 sec)
mysql> explain select /*+ read_from_storage(tiflash[t1]) */ id from t1 order by vec_cosine_distance(vec, '[1,1,1]') limit 10;
+--------------------------------+---------+--------------+---------------+-----------------------------------------------------------------+
| id | estRows | task | access object | operator info |
+--------------------------------+---------+--------------+---------------+-----------------------------------------------------------------+
| TopN_10 | 10.00 | root | | Column#7, offset:0, count:10 |
| └─TableReader_21 | 10.00 | root | | MppVersion: 2, data:ExchangeSender_20 |
| └─ExchangeSender_20 | 10.00 | mpp[tiflash] | | ExchangeType: PassThrough |
| └─TopN_19 | 10.00 | mpp[tiflash] | | Column#7, offset:0, count:10 |
| └─Projection_18 | 10.00 | mpp[tiflash] | | test.t1.id, vec_cosine_distance(test.t1.vec, [1,1,1])->Column#7 |
| └─TableFullScan_17 | 100.00 | mpp[tiflash] | table:t1 | keep order:false, stats:pseudo |
+--------------------------------+---------+--------------+---------------+-----------------------------------------------------------------+
6 rows in set (0.00 sec)
1. Minimal reproduce step (Required)
CREATE TABLE t1 (
id INT PRIMARY KEY,
vec VECTOR(3),
VECTOR INDEX idx_vec ((VEC_COSINE_DISTANCE(vec)))
);
INSERT INTO t1 (id, vec)
WITH RECURSIVE numbers(n) AS (
SELECT 1
UNION ALL
SELECT n + 1 FROM numbers WHERE n < 100
)
SELECT
n AS id,
CONCAT('[', RAND(), ',', RAND(), ',', RAND(), ']') AS vec
FROM numbers;
alter table t1 compact;
select /*+ read_from_storage(tikv[t1]) */ id from t1 order by vec_cosine_distance(vec, '[1,1,1]') limit 10;
+-----+
| id |
+-----+
| 16 |
| 67 |
| 59 |
| 28 |
| 94 |
| 26 |
| 53 |
| 65 |
| 100 |
| 31 |
+-----+
10 rows in set (0.02 sec)
select /*+ read_from_storage(tiflash[t1]) */ id from t1 order by vec_cosine_distance(vec, '[1,1,1]') limit 10;
+-----+
| id |
+-----+
| 59 |
| 16 |
| 53 |
| 67 |
| 28 |
| 65 |
| 94 |
| 31 |
| 26 |
| 100 |
+-----+
10 rows in set (0.01 sec)
2. What did you expect to see? (Required)
Same results
3. What did you see instead (Required)
different results
4. What is your TiFlash version? (Required)
tidb-cse: release-7.5-keyspace
tiflash-cse: cloud-engine-on-release-8.5
tikv-cse: cloud-engine
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the SQL reproduction and EXPLAIN plans comparing the forced tikv and tiflash paths. Trace how each path calculates and sorts vec_cosine_distance results, then verify the fix by running the provided dataset and confirming both paths return the same top 10 ids.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- databases, search
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 32/100