This patch changes int2_avg_accum() and int4_avg_accum() use the nodeAgg
performance hack Tom introduced recently. This means we can avoid copying the transition array for each input tuple if these functions are invoked as aggregate transition functions. To test the performance improvement, I created a 1 million row table with a single int4 column. Without the patch, SELECT avg(col) FROM table took about 4.2 seconds (after the data was cached); with the patch, it took about 3.2 seconds. Naturally, the performance improvement for a less trivial query (or a table with wider rows) would be relatively smaller.
This commit is contained in:
parent
8bbe905a2e
commit
51b2f8ba55
@ -14,7 +14,7 @@
|
||||
* Copyright (c) 1998-2005, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.81 2005/01/01 05:43:07 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.82 2005/04/04 23:50:27 neilc Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -2462,17 +2462,24 @@ typedef struct Int8TransTypeData
|
||||
Datum
|
||||
int2_avg_accum(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ArrayType *transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
|
||||
ArrayType *transarray;
|
||||
int16 newval = PG_GETARG_INT16(1);
|
||||
Int8TransTypeData *transdata;
|
||||
|
||||
/*
|
||||
* We copied the input array, so it's okay to scribble on it directly.
|
||||
* If we're invoked by nodeAgg, we can cheat and modify our first
|
||||
* parameter in-place to reduce palloc overhead. Otherwise we need
|
||||
* to make a copy of it before scribbling on it.
|
||||
*/
|
||||
if (fcinfo->context && IsA(fcinfo->context, AggState))
|
||||
transarray = PG_GETARG_ARRAYTYPE_P(0);
|
||||
else
|
||||
transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
|
||||
|
||||
if (ARR_SIZE(transarray) != ARR_OVERHEAD(1) + sizeof(Int8TransTypeData))
|
||||
elog(ERROR, "expected 2-element int8 array");
|
||||
transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
|
||||
|
||||
transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
|
||||
transdata->count++;
|
||||
transdata->sum += newval;
|
||||
|
||||
@ -2482,17 +2489,24 @@ int2_avg_accum(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
int4_avg_accum(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ArrayType *transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
|
||||
ArrayType *transarray;
|
||||
int32 newval = PG_GETARG_INT32(1);
|
||||
Int8TransTypeData *transdata;
|
||||
|
||||
/*
|
||||
* We copied the input array, so it's okay to scribble on it directly.
|
||||
* If we're invoked by nodeAgg, we can cheat and modify our first
|
||||
* parameter in-place to reduce palloc overhead. Otherwise we need
|
||||
* to make a copy of it before scribbling on it.
|
||||
*/
|
||||
if (fcinfo->context && IsA(fcinfo->context, AggState))
|
||||
transarray = PG_GETARG_ARRAYTYPE_P(0);
|
||||
else
|
||||
transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
|
||||
|
||||
if (ARR_SIZE(transarray) != ARR_OVERHEAD(1) + sizeof(Int8TransTypeData))
|
||||
elog(ERROR, "expected 2-element int8 array");
|
||||
transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
|
||||
|
||||
transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
|
||||
transdata->count++;
|
||||
transdata->sum += newval;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user