-
Notifications
You must be signed in to change notification settings - Fork 4k
[improvement](lance) Add ANN prefilter optimization and profiles (branch-4.1) #68615
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
29f3df9
4a86e23
a7ff3f8
8c7f614
1bdd1ea
eb51a98
065e490
7586f8c
4c1f03e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -912,6 +912,15 @@ TEST(LanceTableReaderVectorSearchTest, MultiVectorScoresFiltersOffsetsAndIndexed | |
| } | ||
| EXPECT_TRUE(reader.close().ok()); | ||
| if (indexed) { | ||
| // Warm searches still perform scoring even when every index partition is cached. | ||
| for (const char* name : | ||
| {"LanceIndexPartitionLoadTime", "LanceIndexCpuQueueWaitTime", | ||
| "LanceIndexSearchTime", "LanceIndexQueryPrepareTime", | ||
| "LanceIndexDistanceTopKTime", "LanceIndexResultMaterializeTime"}) { | ||
| auto* counter = profile.get_counter(name); | ||
| ASSERT_NE(nullptr, counter) << name; | ||
| EXPECT_GT(counter->value(), 0) << name; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [P2] Check ANN timer emission without requiring every duration to be positive. The pinned lance-c timing test explicitly allows zero nanoseconds for short or uncontended stages; this four-result indexed scan requires six independent timers to be |
||
| } | ||
| // Read metrics after close: lance-c publishes its final execution summary | ||
| // when the stream is released, including for an early top-k stop. | ||
| for (const char* name : {"LancePrefilterLoads", "LancePrefilterInputRows", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| <!-- | ||
| Licensed to the Apache Software Foundation (ASF) under one | ||
| or more contributor license agreements. See the NOTICE file | ||
| distributed with this work for additional information | ||
| regarding copyright ownership. The ASF licenses this file | ||
| to you under the Apache License, Version 2.0 (the | ||
| "License"); you may not use this file except in compliance | ||
| with the License. You may obtain a copy of the License at | ||
|
|
||
| http://www.apache.org/licenses/LICENSE-2.0 | ||
|
|
||
| Unless required by applicable law or agreed to in writing, | ||
| software distributed under the License is distributed on an | ||
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| KIND, either express or implied. See the License for the | ||
| specific language governing permissions and limitations | ||
| under the License. | ||
| --> | ||
|
|
||
| # Lance ANN profile timings | ||
|
|
||
| `FileScannerV2` accumulates scanner initialization, open, block-read, and close | ||
| wall time. Range acquisition and split preparation are nested within those | ||
| calls, so their counters are not additional time. Scanner worker scheduling | ||
| wait is reported separately. `LanceScannerReadTime` measures time spent calling | ||
| the Lance scanner, including Rust execution and waits. Doris scanner CPU time | ||
| does not include work done on Lance's CPU pool. | ||
|
|
||
| The following counters expose the work within an indexed vector search: | ||
|
|
||
| | Counter | Scope | | ||
| | --- | --- | | ||
| | `LanceIndexOpenTime` | Index-handle lookup/open, including metadata reads on a miss. | | ||
| | `LanceIVFPartitionRankingTime` | Partition ranking, including its CPU dispatch wait. | | ||
| | `LanceIndexPartitionLoadTime` | Partition cache lookup, coalesced-load wait, and read/decode on a miss. Also measured on cache hits. | | ||
| | `LanceIndexPartitionPrepareTime` | Partition load and per-partition filter preparation. On the streaming path, shared-filter waiting overlaps loading. | | ||
| | `LanceIndexPrefilterWaitTime` | Waiting for the shared prefilter to become ready. This is distinct from building the filter. | | ||
| | `LanceIndexCpuQueueWaitTime` | Delay before a dispatched search or result-materialization CPU task starts. | | ||
| | `LanceIndexSearchTime` | Search of prepared partitions on the CPU pool, including query preparation and any per-partition result construction. | | ||
| | `LanceIndexQueryPrepareTime` | Distance-calculator / lookup-table construction in the IVF flat sub-index (including quantized storage). | | ||
| | `LanceIndexDistanceTopKTime` | Candidate filtering, distance evaluation, and heap updates in that sub-index. These operations are fused in fast-scan paths. | | ||
| | `LanceIndexResultMaterializeTime` | Converting result heaps into Arrow arrays and batches, excluding final global sorting. | | ||
| | `LanceANNPartitionExecTime`, `LanceANNSubIndexExecTime`, `LanceANNBatchExecTime` | Baseline elapsed times reported by the corresponding Lance ANN operators. These include asynchronous waits. | | ||
| | `LanceSortComputeTime`, `LanceSortMergeComputeTime` | DataFusion sort / sort-preserving merge operator compute times. | | ||
| | `LanceTakeExecTime` | Baseline time reported by Lance's take operator within the scan plan. Doris second-phase row-ID fetch has separate counters. | | ||
| | `LanceVectorDistanceComputeTime` | Baseline reported by the vector-distance operator, e.g. refinement or an unindexed tail. | | ||
|
|
||
| Timings accumulate across partitions, tasks, and index segments. They are | ||
| **nested and may overlap**, so summing them does not reconstruct query wall time. | ||
| In particular, partition preparation contains loading; search contains query | ||
| preparation and distance/TopK work; ANN operator baselines contain downstream | ||
| search stages and waits. A zero counter can mean the corresponding operator or | ||
| path was not used. Detailed sub-index timers currently cover IVF flat sub-indices; | ||
| other sub-indices are visible through the encompassing search timer. | ||
|
|
||
| `LancePrefilterLoadTime` includes `LancePrefilterInputTime` and | ||
| `LancePrefilterBuildTime`; do not add these three together. A segment-scoped | ||
| search without a predicate can avoid constructing the row-ID allowlist, while | ||
| still respecting deletions and fragment visibility. Filter-readiness waiting can | ||
| therefore remain nonzero even when the row-ID materialization counters are zero. | ||
|
|
||
| For a warm query with no execution I/O and no prefilter materialization, inspect | ||
| CPU queue wait, query preparation, distance/TopK, and result/sort timers. For cold | ||
| queries, inspect partition load together with execution bytes, requests, and | ||
| partition cache misses. Use repeated queries and the operator-level elapsed | ||
| times to assess latency; cumulative parallel stage times alone are not a critical | ||
| path trace. |
Uh oh!
There was an error while loading. Please reload this page.