Re: POC: GROUP BY optimization
Alexander Korotkov <aekorotkov@gmail.com>
From: Alexander Korotkov <aekorotkov@gmail.com>
To: Andrei Lepikhov <a.lepikhov@postgrespro.ru>
Cc: Tom Lane <tgl@sss.pgh.pa.us>, Richard Guo <guofenglinux@gmail.com>, Pavel Borisov <pashkin.elfe@gmail.com>, vignesh C <vignesh21@gmail.com>, PostgreSQL Developers <pgsql-hackers@lists.postgresql.org>, Tomas Vondra <tomas.vondra@enterprisedb.com>,
Teodor Sigaev <teodor@sigaev.ru>, David Rowley <dgrowleyml@gmail.com>, "a.rybakina" <a.rybakina@postgrespro.ru>
Date: 2024-04-22T22:19:59Z
Lists: pgsql-hackers
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Restore preprocess_groupclause()
- 505c008ca37c 17.0 landed
-
Rename PathKeyInfo to GroupByOrdering
- 0c1af2c35c7b 17.0 landed
-
Add invariants check to get_useful_group_keys_orderings()
- 91143c03d4ca 17.0 landed
-
Fix asymmetry in setting EquivalenceClass.ec_sortref
- 199012a3d844 17.0 landed
-
Multiple revisions to the GROUP BY reordering tests
- 874d817baa16 17.0 landed
-
Get rid of pg_class usage in SJE regression tests
- e1b7fde418f2 17.0 landed
-
Rename index "abc" in aggregates.sql
- b91f91870828 17.0 landed
-
Explore alternative orderings of group-by pathkeys during optimization.
- 0452b461bc40 17.0 landed
-
Generalize the common code of adding sort before processing of grouping
- 7ab80ac1caf9 17.0 landed
-
Fix out-dated comment in preprocess_groupclause()
- f6c70b81802a 15.0 landed
- 78a9af1a2764 16.0 landed
-
Force parallelism in partition_aggregate
- 2fe6b2a806f2 16.0 landed
- 01474f56981a 15.0 landed
-
Optimize order of GROUP BY keys
- db0d67db2401 15.0 landed
Hi! On Thu, Apr 18, 2024 at 1:57 PM Alexander Korotkov <aekorotkov@gmail.com> wrote: > Thank you for the fixes you've proposed. I didn't look much into > details yet, but I think the main concern Tom expressed in [1] is > whether the feature is reasonable at all. I think at this stage the > most important thing is to come up with convincing examples showing > how huge performance benefits it could cause. I will return to this > later today and will try to provide some convincing examples. I took a fresh look at 0452b461b, and have the following thoughts: 1) Previously, preprocess_groupclause() tries to reorder GROUP BY clauses to match the required ORDER BY order. It only reorders if GROUP BY pathkeys are the prefix of ORDER BY pathkeys or vice versa. So, both of them need to be satisfied by one ordering. 0452b461b also tries to match GROUP BY clauses to ORDER BY clauses, but takes into account an incremental sort. Actually, instead of removing preprocess_groupclause(), we could just teach it to take incremental sort into account. 2) The get_useful_group_keys_orderings() function takes into account 3 orderings of pathkeys and clauses: original order as written in GROUP BY, matching ORDER BY clauses as much as possible, and matching the input path as much as possible. Given that even before 0452b461b, preprocess_groupclause() could change the original order of GROUP BY clauses, so we don't need to distinguish the first two. We could just consider output of new preprocess_groupclause() taking into account an incremental sort and the ordering matching the input path as much as possible. This seems like significant simplification. Let me also describe my thoughts about the justification of the feature itself. As Tom pointed upthread, Sort + Grouping is generally unlikely faster than Hash Aggregate. The main point of this feature is being able to match the order of GROUP BY clauses to the order of the input path. That input path could be Index Scan or Subquery. Let's concentrate on Index Scan. Index Scan can give us the required order, so we can do grouping without Sort or with significantly cheaper Incremental Sort. That could be much faster than Hash Aggregate. But if we scan the full table (or its significant fraction), Index Scan is typically much more expensive than Sequential Scan because of random page access. However, there are cases when Index Scan could be cheaper. 1) If the heap row is wide and the index contains all the required columns, Index Only Scan can be cheaper than Sequential Scan because of lesser volume. 2) If the query predicate is selective enough and matches the index, Index Scan might be significantly cheaper. One may say that if the query predicate is selective enough then there are not that many matching rows, so aggregating them either way isn't a big deal anyway. However, given that data volumes are growing tremendously, it's not hard to imagine that the index selected a small fraction of table rows, but they are still enough to be costly for aggregating. Therefore, I think there are significant cases where matching GROUP BY clauses to the order of the input path could give a substantial improvement over Hash Aggregate. While there are some particular use-cases by Jian He, I hope that above could give some rationale. ------ Regards, Alexander Korotkov