Re: Eager aggregation, take 3
Richard Guo <guofenglinux@gmail.com>
On Sat, Sep 13, 2025 at 3:48 AM Robert Haas <robertmhaas@gmail.com> wrote: > On Fri, Sep 12, 2025 at 5:34 AM Richard Guo <guofenglinux@gmail.com> wrote: > > I really like this idea. Currently, aggtransspace represents an > > estimate of the transition state size provided by the aggregate > > definition. If it's set to zero, a default estimate based on the > > state data type is used. Negative values currently have no defined > > meaning. I think it makes perfect sense to reuse this field so that > > a negative value indicates that the transition state data can grow > > unboundedly in size. > > > > Attached 0002 implements this idea. It requires fewer code changes > > than I expected. This is mainly because that our current code uses > > aggtransspace in such a way that if it's a positive value, that value > > is used as it's provided by the aggregate definition; otherwise, some > > heuristics are applied to estimate the size. For the aggregates that > > accumulate input rows (e.g., array_agg, string_agg), I don't currently > > have a better heuristic for estimating their size, so I've chosen to > > keep the current logic. This won't regress anything in estimating > > transition state data size. > This might be OK, but it's not what I was suggesting: I was suggesting > trying to do a calculation like space_used = -aggtransspace * > rowcount, not just using a <0 value as a sentinel. I've considered your suggestion, but I'm not sure I'll adopt it in the end. Here's why: 1) At the point where we check whether any aggregates might pose a risk of excessive memory usage during partial aggregation, row count information is not yet available. You could argue that we could reorganize the logic to perform this check after we've had the row count, but that seems quite tricky. If I understand correctly, the "rowcount" in this context actually means the number of rows within one partial group. That would require us to first decide on the grouping expressions for the partial aggregation, then compute the group row counts, then estimate space usage, and only then decide whether memory usage is excessive and fall back. This would come quite late in planning and adds nontrivial overhead, compared to the current approach which checks at the very beginning. 2) Even if we were able to estimate space usage based on the number of rows per partial group and determined that memory usage seems acceptable, we still couldn't guarantee that the transition state data won't grow excessively after further joins. Joins can multiply partial aggregates, potentially causing a blowup in memory usage even if the initial estimate seemed safe. 3) I don't think "-aggtransspace * rowcount" reflects the true memory footprint for aggregates that accumulate input rows. For example, what if we have an aggregate like string_agg(somecolumn, 'a very long delimiter')? 4) AFAICS, the main downside of the current approach compared to yours is that it avoids pushing down aggregates like string_agg() that accumulate input rows, whereas your suggestion might allow pushing them down in some cases where we *think* it wouldn't blow up memory. You might argue that the current implementation is over-conservative. But I prefer to start safe. That said, I appreciate you proposing the idea of reusing aggtransspace, although I ended up using it in a different way than you suggested. - Richard
Commits
-
Fix eager aggregation for semi/antijoin inner rels
- ffeda04259bb 19 (unreleased) landed
-
Cover additional errors and corner conditions in repack.c
- 2670cc298f42 19 (unreleased) cited
-
Fix volatile function evaluation in eager aggregation
- 3a08a2a8b4fd 19 (unreleased) landed
-
Fix collation handling for grouping keys in eager aggregation
- bd94845e8c90 19 (unreleased) landed
-
Rename apply_at to apply_agg_at for clarity
- 1206df04c200 19 (unreleased) landed
-
Fix comment in eager_aggregate.sql
- 36fd8bde1b77 19 (unreleased) landed
-
Remove unnecessary include of "utils/fmgroids.h"
- f997d777adf7 19 (unreleased) landed
-
Implement Eager Aggregation
- 8e11859102f9 19 (unreleased) landed
-
Allow negative aggtransspace to indicate unbounded state size
- 185e30426334 19 (unreleased) landed
-
Add macros for looping through a List without a ListCell.
- 14dd0f27d7cd 17.0 cited
-
Account for the effect of lossy pages when costing bitmap scans.
- 5edc63bda68a 11.0 cited
-
Fix a thinko in join_is_legal: when we decide we can implement a semijoin
- a43b190e3c71 9.0.0 cited