Repository navigation
Conversation
…mates Rename `StatisticsRegistry::default_with_builtin_providers` to `with_experimental_providers` and deprecate the old name. The experimental set holds `FilterStatisticsProvider` and `JoinStatisticsProvider`. Both start from the operator's `statistics_from_inputs` and replace only the values their technique estimates. `JoinStatisticsProvider` only replaces the row count of multi-key inner equi-joins with the product of per-key distinct counts, and no longer falls back to the Cartesian product. `FilterStatisticsProvider` applies the survival model to the input distinct count, capped at the operator's. Deprecate the providers that duplicate operator estimates: Projection, Passthrough, Aggregate, Limit and Union. Closes apache#25571.
|
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 #25969 +/- ##
==========================================
- Coverage 82.69% 82.68% -0.02%
==========================================
Files 1147 1147
Lines 447348 447364 +16
Branches 447348 447364 +16
==========================================
- Hits 369936 369890 -46
- Misses 54999 55058 +59
- Partials 22413 22416 +3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
| `StatisticsRegistry::default_with_builtin_providers()` is deprecated in favor of | ||
| `StatisticsRegistry::with_experimental_providers()`. Most of the providers it |
There was a problem hiding this comment.
For these providers, rather than just moving them to "experimental", it'd be nice to clarify their future and direction.
For example, if they do are experimental, what's that scope of the experiment, is someone investing time in experimenting with them so that at some point they are eligible to replace their equivalent ExecutionPlan::partition_statistics() implementation?
To be honest I don't really see much benefit in having two different concurrent implementations of the same statistics estimation code committed to main in order to keep one implementation as an "experiment". Typically experiments are something confined to a developer's PR until it proves an improvement via benchmarks, and once the improvement is qualified it replaces the previous code, rather than co-living as a mutually exclusive code path in main.
There was a problem hiding this comment.
Thanks for your feeback, @gabotechs.
I was considering a two-phased approach, as the Join and Filter providers had improvements we want to keep, but I agree it's better to file issues for later than to keep duplicate code:
- Multi-key join estimation is already tracked in Use exponential decay for multi-column join selectivity estimation #21583 (I added a comment)
- For NDV estimation after filters, I have filed Estimate distinct counts after a filter with the survival formula in
FilterExec#26052
NDV-based improvements are not covered by the existing benchmarks, as they don't provide NDV yet, but with the work of @Rich-T-kid (#25576) we might get there eventually and be able to merge those, once we can show the numbers get better.
I have updated the PR to deprecate the bundled (formerly known as "built-in") providers entirely. Please take another look when you have time, thanks!
There was a problem hiding this comment.
I was considering a two-phased approach, as the Join and Filter providers had improvements we want to keep
👍 My impression is that we could fold those into the built-in statistics of FilterExec and HashJoinExec, WDYT? (for another PR of course)
There was a problem hiding this comment.
I realized there is some overlap with #25570, but I guess that will land soon and we should wait a bit for this one
There was a problem hiding this comment.
I'd not worry too much, whatever lands first is fine I think
| #[deprecated( | ||
| since = "56.0.0", | ||
| note = "the bundled providers are deprecated; the statistics walk uses each operator's `statistics_from_inputs` when no provider matches" | ||
| )] | ||
| #[expect(deprecated)] |
There was a problem hiding this comment.
👍 looks good. Not sure which tickets are already open for this, but what comes to mind is:
- Fold the improvements brought by these providers into the built-in
partition_statisticsmethod. - Remove the now redundant providers
There was a problem hiding this comment.
The two follow-up issues are listed here, which follow your proposal 1. to fold improvements in the built-in estimation.
For 2. I have filed #26055 following https://datafusion.apache.org/contributor-guide/api-health.html#deprecation-guidelines so we won't forget.
| // Replaces the join estimate with the Cartesian product | ||
| let join_provider = ClosureStatisticsProvider::with_matches( | ||
| |plan| plan.downcast_ref::<HashJoinExec>().is_some(), |
There was a problem hiding this comment.
I see this is still using a ClosureStatisticsProvider. I see this is mainly just for testing that the registry still works and actually listens to what the ClosureStatisticsProvider has to say.
If it's just that, all good, but let me know if missed something.
There was a problem hiding this comment.
Yes, I trimmed the example down to exactly that, just testing the registry works, you got it right
|
Thanks @asolimando! |
Which issue does this PR close?
Rationale for this change
StatisticsRegistry::default_with_builtin_providers()registers providers that are not the default estimation and that duplicate or replace what the operators already do instatistics_from_inputs. They can make estimates worse (TPC-H Q14: 14.73 billion rows instead of 73,650, see #25570), and fixes in the operators do not reach their users. Estimation improvements belong in the operators;StatisticsRegistrystays as the extension point for user-defined providers.What changes are included in this PR?
default_with_builtin_providers()and all seven bundled providers are deprecated. Their code is unchanged.statistics_registry.sltand thejoin_reorderexample use user-defined providers instead of bundled ones.dfbench statisticsreports the operators' own estimates instead of the bundled providers' estimates.Follow-ups: moving the Filter distinct count survival model into
FilterExec(#26052); multi-key join estimation is tracked in #21583.What is the testing strategy for this PR?
statistics_registry.sltpasses unchanged; thejoin_reorderexample still flips the build side.Are there any user-facing changes?
Deprecations only, see the 56.0.0 upgrade guide.
Disclaimer: I used AI to assist in the code generation, I have manually reviewed the output and it matches my intention and understanding.