Re: Eager aggregation, take 3
Richard Guo <guofenglinux@gmail.com>
Attachments
- v23-0001-Implement-Eager-Aggregation.patch (application/octet-stream) patch v23-0001
- v23-0002-Allow-negative-aggtransspace-to-indicate-unbound.patch (application/octet-stream) patch v23-0002
I've run TPC-DS again to compare planning times with and without eager aggregation. Out of 99 queries, only one query (query 64) shows a noticeable increase in planning time. This query performs inner joins across 38 tables. This is a very large search space. (I'm talking about the standard join search method, not the GEQO.) If my math doesn't fail me, the maximum number of different join orders when joining n tables is: Catalan(n − 1) x n!. For n = 38, this number is astronomically large. In practice, query 64 joins 19 tables twice (due to a CTE), which still results in about 3.4E28 different join orders. Of course, in practice, with the help of join_collapse_limit and other heuristics, the effective search space is reduced a lot, but even then, it remains very large. Given this, I'm not too surprised that query 64 shows an increase in planning time when eager aggregation is applied -- exploring the best join order in such a space is inherently expensive. That said, I've identified a few performance hotspots that can be optimized to help reduce planning time: 1) the exprs_known_equal() call in get_expression_sortgroupref(), which is used to check if a given expression is known equal to a grouping expression due to ECs. We can optimize this by storing the EC of each grouping expression, and then get_expression_sortgroupref() would only need to search the relevant EC, rather than scanning all of them. 2) the estimate_num_groups() call in create_rel_agg_info(). We can optimize this by avoiding unnecessary calls to estimate_num_groups() where possible. Attached is an updated version of the patch with these optimizations applied. With this patch, the planning times for query 64, with and without eager aggregation, are: -- with eager aggregation Planning Time: 9432.042 ms -- without eager aggregation Planning Time: 7196.999 ms I think the increase in planning time is acceptable given the large search space involved, though I may be biased. - 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