[improvement](lance) Balance fragment splits by row count - #66597
Conversation
|
run buildall |
FE Regression Coverage ReportIncrement line coverage |
|
PR approved by at least one committer and no changes requested. |
|
PR approved by anyone and no changes requested. |
|
/review |
There was a problem hiding this comment.
Automated code review: changes requested.
Critical checkpoints:
- Scheduling correctness: the catalog path now produces bounded weights that reach
FederationBackendPolicy, but S3/file Lance TVFs still discard fragment row counts and remain equally weighted. - Compatibility and performance: FE uses logical rows after deletions, while the pinned BE Lance legacy reader applies deletions only after reading and merging physical batches, so tombstone-heavy legacy fragments can be severely underweighted.
- Query semantics and protocol: split count/order, pinned version and fragment IDs, scan-range serialization, and the intentional single-split local-TVF/vector-search modes remain unchanged; no query-result or protocol defect was found.
- Tests: the new unit test covers standard, proportional, and minimum raw weights, but does not cover S3/file TVF parity or deletion-heavy legacy fragments.
- User focus: no additional focus was supplied; the full PR was reviewed.
- Completion: the review converged in two rounds with every candidate accepted, deduplicated, or dismissed; two inline issues are attached.
| } | ||
| splits.add(new LanceSplit(metadata.getDatasetUri(), metadata.getVersion(), | ||
| fragment.getId(), fragment.getRowCount())); | ||
| targetRows = Math.max(targetRows, Math.max(fragment.getRowCount(), 1)); |
There was a problem hiding this comment.
[P2] Base legacy-fragment weights on physical scan work
fragment.getRowCount() comes from Java FragmentMetadata#getNumRows(), which is physical rows minus deletions. However, the BE links lance-c 0.1.2/Lance 4.0.1, whose legacy fragment reader reads and merges the projected physical batches before applying the deletion vector. A legacy fragment with 1,000,000 physical rows and 990,000 tombstones can therefore receive only a 1 percent weight even though its scan still does close to a full fragment's I/O/decoding work; compared with the previous equal weights, this can actively co-locate expensive tombstone-heavy fragments. Please use physical rows or another format-aware scan-cost metric for this normalization and cover a deletion-heavy legacy fragment.
| for (LanceTableMetadata.LanceFragmentInfo fragment : metadata.getFragments()) { | ||
| LanceSplit split = new LanceSplit(metadata.getDatasetUri(), metadata.getVersion(), | ||
| fragment.getId(), fragment.getRowCount()); | ||
| split.setTargetSplitSize(targetRows); |
There was a problem hiding this comment.
[P2] Keep S3/file TVF fragment weights in sync
This sets the common target only for catalog-backed LanceScanNode splits. The S3 Lance TVF path loads the same fragment row counts via loadLatestForTvf(), but setLanceTableMetadata() retains only IDs; TVFScanNode#getLanceSplits() then passes rowCount=1 and never sets a target. The file(...) TVF delegates S3 Lance scans to this same path, so both entry points still give every fragment the standard scheduling weight and keep the skew this change is intended to remove. Please retain row counts through the TVF metadata boundary, apply the same normalization there, and add a parity test for that split path.
FE Regression Coverage ReportIncrement line coverage |
What problem does this PR solve?
Lance fragment metadata already carries the visible row count, and
LanceSplitstores it asselfSplitWeight. However,FileSplit#getSplitWeightonly uses that value when a commontargetSplitSizeis set. As a result, all Lance fragments currently have the same standard scheduling weight regardless of row count, which can cause uneven scan work across BEs when fragment sizes differ.This PR uses the largest fragment row count as one standard split and assigns smaller fragments a proportional weight. It changes only FE scheduling metadata:
Verification
LanceScanNodeTestcovering fragment row counts1000,250, and0, which map to raw split weights100,25, and the minimum1.mvn validate -pl fe-core -am -DskipTestspassed for all 15 FE reactor modules with zero Checkstyle violations.Check List