introduce optional rle reads from parquet - #24227
Conversation
| // to Dictionary(Int32, ...) so the parquet reader produces dictionary arrays. | ||
| // All three schemas are updated together so the reader, expr-adapter, and | ||
| // downstream operators all agree on the output type. | ||
| if prepared.enable_rle_to_dictionary { |
There was a problem hiding this comment.
All three schemas are updated together so the reader, expr-adapter, and downstream operators all agree on the output type.
| pub max_in_list_size: usize, default = 20 | ||
|
|
||
| /// (reading) If true, string and binary columns that are dictionary-encoded in | ||
| /// the parquet file are read as `Dictionary<Int32, Utf8>` / `Dictionary<Int32, Binary>` |
There was a problem hiding this comment.
I choose to keep the key type hard coded to int32 instead of u64, would not mind changing
|
Thank you for opening this pull request! Reviewer note: cargo-semver-checks reported the current version number is not SemVer-compatible with the changes in this pull request (compared against the base branch). Details |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #24227 +/- ##
==========================================
+ Coverage 81.14% 81.18% +0.04%
==========================================
Files 1112 1109 -3
Lines 386933 388424 +1491
Branches 386933 388424 +1491
==========================================
+ Hits 313978 315345 +1367
- Misses 54462 54534 +72
- Partials 18493 18545 +52 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@adriangb pinging you since you seem interested in parquet related speed ups 👍 |
|
If I understand correctly the goal is to evaluate filters during filter pushdown against dictionary / RLE encoded columns? We can't propagate these dynamic type changes to the rest of the query plan / scan. Is that right? |
no not exactly. The goal of this PR is to keep RLE parquet columns in their compacted form by materializing them as dictionary arrays instead of regular strings.
exactly! This is why it needs to be done as early in the plan as possible. we inspect |
0479f9c to
6e1cbc1
Compare
Why only RLE and not dictionaries as well? How does this compare to / relate to the It also looks like this goes through I'd be more interested in seeing something at the parquet scan level that was able to e.g. optimize how row filters are applied by applying them to the dictionary instead of expanding into |
6a4e89d to
d1273bf
Compare
my bad when I say RLE i'm referring to
I agree, ill update the PR to target all parquet scans. |
|
@adriangb your comments are addressed in 8bc183b
To keep planning and execution in sync, the opener also rewrites the physical read schema so arrow-rs produces dict arrays. Without the planning-time promotion, downstream operators (FilterExec, AggregateExec) would be compiled against testAdded tests covering:
|
|
ideally we surface columns that are physically RLE_DICTIONARY-encoded in the parquet file as Arrow To know whether a specific column is RLE_DICTIONARY-encoded you need to read the parquet file footer. For the Downstream physical operators ( So when the flag is enabled we promote all string/binary columns to dict at planning time, not just the ones that are actually RLE-encoded, because that's the only way to guarantee schema consistency across all parquet scan paths without introducing file I/O into the planning stage. I feel like i'm missing something here. if we could take a peak at the parquets metadata before physical planning and change the schema for all operators from the point forward that would be perfect. Im not sure this is currently possible |
Which issue does this PR close?
Rationale for this change
When DataFusion reads a parquet file with dictionary-encoded string or binary columns, it currently decodes the dictionary and returns plain Utf8/Binary arrays, discarding the encoding. For low-cardinality columns (status, country, category, etc.) this doesn't take full advantage of the compacted format parquet gives the engine Preserving the dictionary encoding reduces memory usage and can improve aggregation performance on these columns.
What changes are included in this PR?
Adds
datafusion.execution.parquet.enable_rle_to_dictionary(default false). When enabled:DFParquetMetadata::fetch_schemarewrites dictionary-encoded string/binary fields toDictionary(Int32, Utf8/Binary)at schema inference time, so physical plans are built with the correct typesAre these changes tested?
Dictionary(Int32, Utf8)/Dictionary(Int32, Binary)when the flag is enabled, and as plain types when disabledarrow_typeof()to assert the physical Arrow type changes between the two flag statesAre there any user-facing changes?
New session config option:
SET datafusion.execution.parquet.enable_rle_to_dictionary = true. Default is false so existing behavior is unchanged.