Conversation
Change-Id: I94c3cd431bcf5ba4bee7906838fa2d7cd4f6769e
|
CI RED is expected since it rely on lance-format/lance#7169 |
|
@summaryzb thanks for working on this. Quick data point in case it's useful: Measured driver-side single-machine
Wondering whether the distributed path can beat sub-100ms single-machine once you account for Spark task scheduling overhead — would you be able to share end-to-end latency numbers from your benchmark setup at a similar scale? Would help inform docs around when to enable Thanks! |
|
Thanks for driving this work. This PR is very important for our Spark + Gravitino + Lance query path. Gravitino serves as the catalog/control plane, but it does not execute the Now that the prerequisite support for selecting vector index segments through the Lance Java/JNI scan API has been merged, would you be interested in continuing this PR? Thanks again! |
Filter semantics differ between indexed units and fallback unitsWhile testing this PR (merged onto #819, which supplies the
boolean fallbackUnit = p.getIndexSegments().isEmpty();
boolean userRequestedPrefilter = Boolean.TRUE.equals(base.getPrefilter());
if (userRequestedPrefilter || fallbackUnit) {
b.prefilter(true);
}Indexed units therefore post-filter: each unit takes its own top-k first, then applies the filter, and the global merge combines those already-truncated per-unit results. Repro4 fragments x 64 rows,
Reproduced both against a local Note this also interacts with the default: SuggestionApply the same prefilter decision to both unit kinds whenever a filter is present. Fallback units already have to prefilter (the A regression test that builds an indexed and an unindexed copy of the same table and asserts both return the same filtered rows would catch this — that is what surfaced it here. |
| resolvedQuery, | ||
| u.fragmentIds, | ||
| u.indexSegments, | ||
| readOptions, |
There was a problem hiding this comment.
readOptions need to pinOpenedRef
We can refer to the logic of LanceScan.
| q.setRefineFactor(base.getRefineFactor()); | ||
| } | ||
|
|
||
| ScanOptions.Builder b = new ScanOptions.Builder().nearest(q.build()); |
There was a problem hiding this comment.
we can add distance ranger support after this pr merge
Summary
Implements distributed execution for the
VECTOR_SEARCHtable function, enabling Spark-parallel vector similarity search across Lance datasets. When enabled viaspark.sql.lance.search.distributed.enabled=true, the driver plans one Spark task per execution unit(indexed segment or fallback fragment), and each worker runs a local ANN scan or fallback to KNN scan without indexed segment. Results are merged with a global sort on
_distance.This provides horizontal scalability for vector search workloads on large datasets without requiring a centralized vector index server.
Behavior
distributed.enabled=falsenamespace.queryTable()distributed.enabled=true, has vector indexfastSearch=true)distributed.enabled=true, no indexNotice
CREATE INDEX ... USING IVF_PQSQL support in lance-spark extensions) which is rely on feat: distributed vector index creation #605.prefilter=trueflag is forced for fallback units due to a lance-core JNI limitation whereScanner::nearestrejects fragment-restricted scans without a prefilter expression.indexSegmentsinScanOptionsis pre required which is rely on feat(java): support segment-based distributed vector search lance#7169, other wise compile failsTesting
BaseSparkDistributedVectorSearchTestexercises fallback-only scenarios