Conversation
xiangfu0
force-pushed
the
xiangfu0/data-3221-11-metadata-only-pruning
branch
from
September 9, 2026 01:56
6f1c691 to
9a69689
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## xiangfu0/data-3221-10-physical-column-names #19511 +/- ##
==============================================================================
Coverage 67.76% 67.76%
Complexity 1450 1450
==============================================================================
Files 3494 3494
Lines 225406 225408 +2
Branches 35599 35595 -4
==============================================================================
+ Hits 152738 152746 +8
- Misses 60619 60626 +7
+ Partials 12049 12036 -13
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
xiangfu0
force-pushed
the
xiangfu0/data-3221-11-metadata-only-pruning
branch
from
September 11, 2026 09:32
9a69689 to
68c65e2
Compare
xiangfu0
force-pushed
the
xiangfu0/data-3221-11-metadata-only-pruning
branch
2 times, most recently
from
September 13, 2026 01:13
490463e to
f88c13c
Compare
This was referenced Sep 13, 2026
Open
xiangfu0
removed this pull request from stack #19484
September 13, 2026 01:16
xiangfu0
added this pull request to stack #19540
September 13, 2026 01:17
…alizing them `ColumnValueSegmentPruner` asks each segment for a column's data source and then reads nothing from it but the metadata — data type, min/max, partition function. Reaching that metadata through `getDataSource` makes a segment that builds its columns lazily construct the whole index container, every index reader for the column, for a segment it is about to discard. That runs in `ValueBasedSegmentPruner#prune`, a serial loop over every segment the server holds, on the query thread. On an external table under lazy column materialization it puts a Parquet footer parse there too: on a server holding 44,780 segments the pruner alone accounted for the bulk of a query that timed out at 300 s, for a filter that matched 1,839 segments. `IndexSegment#getDataSourceMetadata(String, Schema)` names what the caller actually wants, defaulting to today's behaviour so no implementation has to change. `ImmutableSegmentImpl` answers it from column metadata: `ImmutableDataSourceMetadata` already delegates to `ColumnMetadata` and holds no readers, so it needs nothing built. A column the segment does not have still falls through to the data source, where the schema-driven default and virtual columns are created. The pruner keeps its per-segment data-source cache for mutable segments, whose metadata is not derivable without the data source. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
xiangfu0
force-pushed
the
xiangfu0/data-3221-11-metadata-only-pruning
branch
from
September 13, 2026 04:14
f88c13c to
6b4dab2
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
ColumnValueSegmentPrunerasks each segment for a column'sDataSourceand then reads nothing from it but theDataSourceMetadata— data type, min/max, partition function. Reaching that metadata throughgetDataSourceforces a segment that builds its columns lazily to construct the wholeColumnIndexContainer— every index reader for the column — for a segment it is about to discard.This adds
IndexSegment#getDataSourceMetadata(String, Schema), which names what the caller actually wants and defaults togetDataSource(column, schema).getDataSourceMetadata(), so no existing implementation has to change.ImmutableSegmentImploverrides it to answer from column metadata:ImmutableDataSourceMetadataalready delegates toColumnMetadataand holds no readers, so nothing needs building. A column the segment does not have still falls through to the data source, which is where the schema-driven default and virtual columns are created.The pruner keeps its per-segment data-source cache for mutable segments, whose metadata is not derivable without the data source.
Why
ValueBasedSegmentPruner#pruneis a serial loop over every segment the server holds, on the query thread — it implements only the two-argprune, soSegmentPruner's three-arg default silently discards theExecutorService(BloomFilterSegmentPruner, by contrast, does override it and prunes in parallel).Combined with lazy column materialization (#19477) that means the pruner materializes a column per held segment, and on a tiered-storage external table each materialization parses a Parquet footer. Measured on a production server holding 44,780 segments, this dominated a query that timed out at 300 s for a filter matching 1,839 segments — the pruner was doing tens of thousands of footer parses, in series, for segments it then discarded.
The win is not limited to lazy mode: building an index container to read min/max is wasted work in any configuration.
Tests
ImmutableSegmentImplTest#testDataSourceMetadataDoesNotMaterializeTheColumnbuilds a lazy segment with a mockedColumnMaterializer, reads the metadata, and assertsverifyNoInteractions(materializer)— then shows that asking for the data source does materialize, and that the two agree. It fails when the override is removed.51 pruner tests in pinot-core and 35 segment tests in pinot-segment-local pass; spotless, checkstyle and license clean.
Stack
Based on #19486. Review this PR against its base for this layer's changes.
Current open chain; #19480 (lazy index-size storage) is already merged, and #19476 is absorbed into #19473.