You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Successor to #289, which is closed. That issue's diagnosis came from a profile taken while column projection was silently broken (#338), and its headline claim has since been measured and contradicted: on the 100M bench, serial-to-serial, pgColumnar now runs its q6 shape in 4,357 ms against TimescaleDB's 5,597 ms. This issue covers what measurement says actually remains.
The gap, verified in code
Grouped aggregates receive none of the vectorized aggregate work that landed under #289.
ColumnarCreateUpperPaths (src/columnar_vector.c:816-829) branches on the query shape. When groupClause != NIL it either adds the grouped path or nothing, and then returns -- so #337 (serial batch fold), #343 (parallel partial agg) and #346 (int partials) are unreachable for any grouped query.
behind pgcolumnar.enable_group_vectorization, default off
that node's parallelism
none -- parallel_aware = false, parallel_workers = 0 (src/columnar_vector.c:938-940), and columnar_groupagg_exec_methods declares no DSM callbacks
So a default install answers a grouped aggregate with a projected scan feeding an ordinary row-wise Agg.
This is not a niche shape. Three of the four TSBS queries in #289's own table -- q4 (group by host), q5 (10 aggregates, grouped), q8 (top 20 by max) -- are grouped.
What is deliberately NOT claimed here
Nothing about the size of this. No grouped shape has been measured on current main. The published q4/q5 figures in docs/benchmarks.md show pgColumnar losing to heap, but those predate #339 (see #348), so they say nothing about today.
That is the specific mistake #289 made -- a plan built on a profile rather than on a measurement of the thing being planned -- and it is worth not repeating in its successor.
First step: measure, then decide
Before any implementation, on the 100M bench, current main, fixtures asserted, buffers alongside times, all arms in one session:
q4, q5 and q8 with projection on vs off. Establishes what the one lever that already applies is worth on grouped shapes.
The same with enable_group_vectorization on vs off. Establishes whether the existing Grouped vectorized aggregate (#289) #321 node earns its keep, and whether its default-off is the right default.
Only after that should anyone choose between: making the grouped node parallel-aware, extending the batch fold to grouped shapes, or turning enable_group_vectorization on by default.
Second item, independent of the above
The batch fold pushes no scan keys, so it forfeits zone-map group pruning. ColumnarBeginRead is called with nkeys = 0 from the fold path, and with no predicates columnar_build_predicates returns immediately, so no group skipping and no vector skipping occurs.
On a randomly filled fixture this costs nothing -- no group's min/max rules out usage_user > 90.0, so nothing would have been pruned. On clustered or time-ranged data, which is the TSBS-shaped workload, enabling the fold may trade pruning for folding, and the sign of that trade is not obvious.
Detectable without any timing: under the fold, EXPLAIN reports Columnar Chunk Groups Removed by Filter: 0 regardless of how selective the predicate is. Worth confirming on a clustered fixture before it bites someone.
Third item
Three of the four levers default off (enable_ungrouped_vector_agg, enable_parallel_vector_agg, enable_group_vectorization). A default install gets projection and nothing else. Whether that is intended is a separate decision, but it should be a decision rather than an accident, and the defaults should be stated wherever performance numbers are published.
Successor to #289, which is closed. That issue's diagnosis came from a profile taken while column projection was silently broken (#338), and its headline claim has since been measured and contradicted: on the 100M bench, serial-to-serial, pgColumnar now runs its q6 shape in 4,357 ms against TimescaleDB's 5,597 ms. This issue covers what measurement says actually remains.
The gap, verified in code
Grouped aggregates receive none of the vectorized aggregate work that landed under #289.
ColumnarCreateUpperPaths(src/columnar_vector.c:816-829) branches on the query shape. WhengroupClause != NILit either adds the grouped path or nothing, and then returns -- so #337 (serial batch fold), #343 (parallel partial agg) and #346 (int partials) are unreachable for any grouped query.What a grouped aggregate actually gets today:
pgcolumnar.enable_group_vectorization, default offparallel_aware = false,parallel_workers = 0(src/columnar_vector.c:938-940), andcolumnar_groupagg_exec_methodsdeclares no DSM callbacksSo a default install answers a grouped aggregate with a projected scan feeding an ordinary row-wise
Agg.This is not a niche shape. Three of the four TSBS queries in #289's own table -- q4 (group by host), q5 (10 aggregates, grouped), q8 (top 20 by max) -- are grouped.
What is deliberately NOT claimed here
Nothing about the size of this. No grouped shape has been measured on current main. The published q4/q5 figures in
docs/benchmarks.mdshow pgColumnar losing to heap, but those predate #339 (see #348), so they say nothing about today.That is the specific mistake #289 made -- a plan built on a profile rather than on a measurement of the thing being planned -- and it is worth not repeating in its successor.
First step: measure, then decide
Before any implementation, on the 100M bench, current main, fixtures asserted, buffers alongside times, all arms in one session:
enable_group_vectorizationon vs off. Establishes whether the existing Grouped vectorized aggregate (#289) #321 node earns its keep, and whether its default-off is the right default.could not read blocks 0..0, see docs/benchmarks.md cross-engine table was measured before column projection landed and understates pgColumnar by ~50x on q6 #348), so cross-engine parallel numbers are not available until that is repaired.Only after that should anyone choose between: making the grouped node parallel-aware, extending the batch fold to grouped shapes, or turning
enable_group_vectorizationon by default.Second item, independent of the above
The batch fold pushes no scan keys, so it forfeits zone-map group pruning.
ColumnarBeginReadis called withnkeys = 0from the fold path, and with no predicatescolumnar_build_predicatesreturns immediately, so no group skipping and no vector skipping occurs.On a randomly filled fixture this costs nothing -- no group's min/max rules out
usage_user > 90.0, so nothing would have been pruned. On clustered or time-ranged data, which is the TSBS-shaped workload, enabling the fold may trade pruning for folding, and the sign of that trade is not obvious.Detectable without any timing: under the fold, EXPLAIN reports
Columnar Chunk Groups Removed by Filter: 0regardless of how selective the predicate is. Worth confirming on a clustered fixture before it bites someone.Third item
Three of the four levers default off (
enable_ungrouped_vector_agg,enable_parallel_vector_agg,enable_group_vectorization). A default install gets projection and nothing else. Whether that is intended is a separate decision, but it should be a decision rather than an accident, and the defaults should be stated wherever performance numbers are published.