Re: Deduplicate aggregates and transition functions in planner - Mailing list pgsql-hackers
From | Andres Freund |
---|---|
Subject | Re: Deduplicate aggregates and transition functions in planner |
Date | |
Msg-id | 20201028195901.t55yiwmxe3quguot@alap3.anarazel.de Whole thread Raw |
In response to | Deduplicate aggregates and transition functions in planner (Heikki Linnakangas <hlinnaka@iki.fi>) |
Responses |
Re: Deduplicate aggregates and transition functions in planner
|
List | pgsql-hackers |
Hi, On 2020-10-28 21:10:41 +0200, Heikki Linnakangas wrote: > Currently, ExecInitAgg() performs quite a lot of work, to deduplicate > identical Aggrefs, as well as Aggrefs that can share the same transition > state. That doesn't really belong in the executor, we should perform that > work in the planner. It doesn't change from one invocation of the plan to > another, and it would be nice to reflect the state-sharing in the plan > costs. Woo! Very glad to see this tackled. It wouldn't surprise me to see a small execution time speedup here - I've seen the load of the aggno show up in profiles. > Attached is a patch to do that. It adds two new fields to Aggref, 'aggno' > and 'aggtransno', to identify the unique aggregate and transition states. > The duplicates are detected, and those filled in, early in the planning. > Aside from those fields, the planner doesn't pass any other new information > to to the executor, so the the executor still has to do syscache lookups to > get the transition, combine etc. functions. > I tried a bigger refactoring at first, to pass more information from the > planner to the executor, but the patch grew really large before I got very > far with it. So as the first step, I think we should apply the attached > patch, and further refactoring can be done after that, if it seems > worthwhile. Working incrementally makes sense. > @@ -783,14 +783,13 @@ ExecInitExprRec(Expr *node, ExprState *state, > > scratch.opcode = EEOP_AGGREF; > scratch.d.aggref.astate = astate; > - astate->aggref = aggref; > + astate->aggno = aggref->aggno; > > if (state->parent && IsA(state->parent, AggState)) > { > AggState *aggstate = (AggState *) state->parent; > > - aggstate->aggs = lappend(aggstate->aggs, astate); > - aggstate->numaggs++; > + aggstate->aggs = lappend(aggstate->aggs, aggref); Hm. Why is aggstate->aggs still built during expression initialization? Imo that's a pretty huge wart that also introduces more order-of-operation brittleness to executor startup. Since AggRef now knows its aggno, the state for EEOP_AGGREF should be changed to be just an int, instead of a pointer to AggrefExprState.. > @@ -3432,8 +3426,18 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) > /* > * We should now have found all Aggrefs in the targetlist and quals. > */ > - numaggs = aggstate->numaggs; > - Assert(numaggs == list_length(aggstate->aggs)); > + numaggrefs = list_length(aggstate->aggs); > + max_aggno = -1; > + max_transno = -1; > + foreach(l, aggstate->aggs) > + { > + Aggref *aggref = (Aggref *) lfirst(l); > + > + max_aggno = Max(max_aggno, aggref->aggno); > + max_transno = Max(max_transno, aggref->aggtransno); > + } > + numaggs = max_aggno + 1; > + numtrans = max_transno + 1; We must have previously determined this, why don't we stash it in struct Agg? > --- a/src/backend/jit/llvm/llvmjit_expr.c > +++ b/src/backend/jit/llvm/llvmjit_expr.c > @@ -1850,19 +1850,11 @@ llvm_compile_expr(ExprState *state) > case EEOP_AGGREF: > { > AggrefExprState *aggref = op->d.aggref.astate; > - LLVMValueRef v_aggnop; > LLVMValueRef v_aggno; > LLVMValueRef value, > isnull; > > - /* > - * At this point aggref->aggno is not yet set (it's set up > - * in ExecInitAgg() after initializing the expression). So > - * load it from memory each time round. > - */ > - v_aggnop = l_ptr_const(&aggref->aggno, > - l_ptr(LLVMInt32Type())); > - v_aggno = LLVMBuildLoad(b, v_aggnop, "v_aggno"); > + v_aggno = l_int32_const(aggref->aggno); Yay! > +/* > + * get_agg_clause_costs > + * Recursively find the Aggref nodes in an expression tree, and > + * accumulate cost information about them. Think this comment is out of date now. Greetings, Andres Freund
pgsql-hackers by date: