Skip to content

q5 is 1.73x slower with the vectorization GUCs on, contradicting an earlier measurement of the same shape #358

Description

@jdatcmd

Summary

On the q5 shape (grouped aggregate, ten avg() metrics, 12-hour window over the 100M TSBS fixture), turning the three optional vectorization GUCs on makes the query 1.73x slower: 16,443 ms to 28,494 ms.

That contradicts an earlier measurement of the same shape where enable_group_vectorization helped. I do not have an explanation, and this issue exists to hold the evidence rather than to assert one.

Not user-visible by default: all three settings default to off.

The two measurements

Both on the bench host, same 100M fixture, same query shape.

Run A, from the #349 measurement phase (labelled G2 there), varying one GUC:

arm time
projection on, group_vectorization off 10,731 ms
projection on, group_vectorization on 8,474 ms

group_vectorization helped, 1.27x.

Run B, from the #348 cross-engine re-measurement:

arm time
pgColumnar defaults 16,443 ms
ungrouped_vector_agg + parallel_vector_agg + group_vectorization all on 28,494 ms

The same setting now appears to hurt, 1.73x, and the absolute numbers do not line up with Run A either: the all-on arm is 8,474 ms in one run and 28,494 ms in the other.

What differs between the runs, in order of how likely I think it is

  1. Run B enables two GUCs that Run A did not. Run A varied only enable_group_vectorization. Run B turned on enable_ungrouped_vector_agg and enable_parallel_vector_agg as well. The interaction between the ungrouped and grouped paths on a grouped ten-aggregate query is the first thing to test, by re-running Run B's arms one GUC at a time.

  2. The grouped path's cost model changed between the runs. fix: charge the grouped aggregate path for the folding it does (#349) #350 landed between them. It charges the grouped path cpu_operator_cost * scan_rows * naggs, so for a ten-aggregate query the charge is ten times what a one-aggregate query gets. That is the intended behaviour, but q5 is exactly the shape where it bites hardest, and it may be selecting a different plan than Run A did. The plans were not captured in Run B, which is the gap that makes this hard to settle from the data on hand.

  3. Ordinary run-to-run variance. Ruled out as a complete explanation: 8,474 against 28,494 is 3.4x, and this box has been stable to a few percent on repeated measurements elsewhere. It may still contribute.

What would settle it

  • Re-run q5 on current main capturing EXPLAIN (ANALYZE) for every arm, not just the timing. Plan choice is the most likely discriminator and was not recorded.
  • Vary the three GUCs independently rather than as a block, so the interaction in (1) is isolated.
  • Check whether the grouped path is chosen in each arm, and if not, what replaced it.

Why it is filed rather than fixed

The measurement is real and repeatable enough to be worth recording, but I cannot name the mechanism, and a guess would be worse than an open question. It is also low urgency: the settings involved all default to off, so no default install is affected.

It was deliberately left out of the docs/benchmarks.md table's narrative in #356 for the same reason. The table reports the number; the surrounding text does not claim to explain it.

Provenance

Observed while re-measuring the cross-engine benchmark for #348. Related to #349, which covers the grouped aggregate path generally.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions