Skip to content

Commit 51b2f8b

Browse files
author
Neil Conway
committed
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.
1 parent 8bbe905 commit 51b2f8b

File tree

1 file changed

+21
-7
lines changed

1 file changed

+21
-7
lines changed

src/backend/utils/adt/numeric.c

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* Copyright (c) 1998-2005, PostgreSQL Global Development Group
1515
*
1616
* IDENTIFICATION
17-
* $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.81 2005/01/01 05:43:07 momjian Exp $
17+
* $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.82 2005/04/04 23:50:27 neilc Exp $
1818
*
1919
*-------------------------------------------------------------------------
2020
*/
@@ -2462,17 +2462,24 @@ typedef struct Int8TransTypeData
24622462
Datum
24632463
int2_avg_accum(PG_FUNCTION_ARGS)
24642464
{
2465-
ArrayType *transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
2465+
ArrayType *transarray;
24662466
int16 newval = PG_GETARG_INT16(1);
24672467
Int8TransTypeData *transdata;
24682468

24692469
/*
2470-
* We copied the input array, so it's okay to scribble on it directly.
2470+
* If we're invoked by nodeAgg, we can cheat and modify our first
2471+
* parameter in-place to reduce palloc overhead. Otherwise we need
2472+
* to make a copy of it before scribbling on it.
24712473
*/
2474+
if (fcinfo->context && IsA(fcinfo->context, AggState))
2475+
transarray = PG_GETARG_ARRAYTYPE_P(0);
2476+
else
2477+
transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
2478+
24722479
if (ARR_SIZE(transarray) != ARR_OVERHEAD(1) + sizeof(Int8TransTypeData))
24732480
elog(ERROR, "expected 2-element int8 array");
2474-
transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
24752481

2482+
transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
24762483
transdata->count++;
24772484
transdata->sum += newval;
24782485

@@ -2482,17 +2489,24 @@ int2_avg_accum(PG_FUNCTION_ARGS)
24822489
Datum
24832490
int4_avg_accum(PG_FUNCTION_ARGS)
24842491
{
2485-
ArrayType *transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
2492+
ArrayType *transarray;
24862493
int32 newval = PG_GETARG_INT32(1);
24872494
Int8TransTypeData *transdata;
24882495

24892496
/*
2490-
* We copied the input array, so it's okay to scribble on it directly.
2497+
* If we're invoked by nodeAgg, we can cheat and modify our first
2498+
* parameter in-place to reduce palloc overhead. Otherwise we need
2499+
* to make a copy of it before scribbling on it.
24912500
*/
2501+
if (fcinfo->context && IsA(fcinfo->context, AggState))
2502+
transarray = PG_GETARG_ARRAYTYPE_P(0);
2503+
else
2504+
transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
2505+
24922506
if (ARR_SIZE(transarray) != ARR_OVERHEAD(1) + sizeof(Int8TransTypeData))
24932507
elog(ERROR, "expected 2-element int8 array");
2494-
transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
24952508

2509+
transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
24962510
transdata->count++;
24972511
transdata->sum += newval;
24982512

0 commit comments

Comments
 (0)