Skip to content

Commit 1226b70

Browse files
committed
perf(knn): reduce memory for batch flat vector search
Avoid retaining whole scan RecordBatches (and vectors) in batch flat KNN heaps when the final projection does not include the vector column. When vectors are requested, retain only a per-row copy.
1 parent 1f7a3eb commit 1226b70

2 files changed

Lines changed: 410 additions & 45 deletions

File tree

rust/lance/src/dataset/scanner.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4424,6 +4424,14 @@ impl Scanner {
44244424
} else {
44254425
input
44264426
};
4427+
let retain_vector = if self.is_batch_nearest {
4428+
let vector_field_id = self.dataset.schema().field_id(q.column.as_str())?;
4429+
self.projection_plan
4430+
.physical_projection
4431+
.contains_field_id(vector_field_id)
4432+
} else {
4433+
false
4434+
};
44274435
let flat_dist = Arc::new(KNNVectorDistanceExec::try_new_batch(
44284436
input,
44294437
&q.column,
@@ -4435,6 +4443,7 @@ impl Scanner {
44354443
lower_bound: q.lower_bound,
44364444
upper_bound: q.upper_bound,
44374445
distance_type: metric_type,
4446+
retain_vector,
44384447
},
44394448
)?);
44404449

@@ -5975,6 +5984,25 @@ mod test {
59755984
}
59765985
assert_batch_matches_single_queries(dataset, &batch, &query_values, k, false, None).await;
59775986

5987+
let mut scan_with_vec = dataset.scan();
5988+
scan_with_vec.nearest("vec", &queries, k).unwrap();
5989+
scan_with_vec.use_index(false);
5990+
scan_with_vec.project(&["i", "vec"]).unwrap();
5991+
let batch_with_vec = scan_with_vec.try_into_batch().await.unwrap();
5992+
assert!(
5993+
batch_with_vec.schema().column_with_name("vec").is_some(),
5994+
"batch flat KNN should return vector column when projected"
5995+
);
5996+
assert_batch_matches_single_queries(
5997+
dataset,
5998+
&batch_with_vec,
5999+
&query_values,
6000+
k,
6001+
false,
6002+
None,
6003+
)
6004+
.await;
6005+
59786006
let query_values_one = (32..64).map(|v| v as f32).collect::<Vec<_>>();
59796007
let queries_one = FixedSizeListArray::try_new_from_values(
59806008
Float32Array::from(query_values_one.clone()),

0 commit comments

Comments
 (0)