From 0b45b1ea5601395b283ae02a3489058c98c50544 Mon Sep 17 00:00:00 2001 From: junhangis Date: Tue, 9 Aug 2022 18:47:33 +0800 Subject: [PATCH] improve the perfomance of numeric additon. before optimization: openGauss=# explain analyse select t0 + t1 from t_numeric limit 10000000; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ Limit (cost=0.00..197973.49 rows=8386919 width=10) (actual time=0.047..10172.644 rows=8388608 loops=1) -> Seq Scan on t_numeric (cost=0.00..197973.49 rows=8386919 width=10) (actual time=0.045..8940.675 rows=8388608 loops=1) Total runtime: 11190.911 ms (3 rows) Time: 11191.776 ms after optimization: openGauss=# explain analyse select t0 + t1 from t_numeric limit 10000000; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ Limit (cost=0.00..197973.49 rows=8386919 width=10) (actual time=0.047..9059.529 rows=8388608 loops=1) -> Seq Scan on t_numeric (cost=0.00..197973.49 rows=8386919 width=10) (actual time=0.044..7869.111 rows=8388608 loops=1) Total runtime: 10048.540 ms (3 rows) Time: 10049.401 ms --- src/common/backend/utils/adt/numeric.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/common/backend/utils/adt/numeric.cpp b/src/common/backend/utils/adt/numeric.cpp index 59a6890be..d1be5002c 100644 --- a/src/common/backend/utils/adt/numeric.cpp +++ b/src/common/backend/utils/adt/numeric.cpp @@ -2125,7 +2125,7 @@ Datum numeric_add(PG_FUNCTION_ARGS) init_var_from_num(num1, &arg1); init_var_from_num(num2, &arg2); - init_var(&result); + quick_init_var(&result); add_var(&arg1, &arg2, &result); res = make_result(&result); @@ -6629,6 +6629,7 @@ static void add_abs(NumericVar* var1, NumericVar* var2, NumericVar* result) int var2ndigits = var2->ndigits; NumericDigit* var1digits = var1->digits; NumericDigit* var2digits = var2->digits; + NumericDigit tdig[NUMERIC_LOCAL_NDIG]; res_weight = Max(var1->weight, var2->weight) + 1; @@ -6644,7 +6645,10 @@ static void add_abs(NumericVar* var1, NumericVar* var2, NumericVar* result) res_ndigits = 1; } - res_buf = digitbuf_alloc(res_ndigits + 1); + res_buf = tdig; + if (res_ndigits > NUMERIC_LOCAL_NMAX) { + res_buf = digitbuf_alloc(res_ndigits + 1); + } res_buf[0] = 0; /* spare digit for later rounding */ res_digits = res_buf + 1; @@ -6671,8 +6675,17 @@ static void add_abs(NumericVar* var1, NumericVar* var2, NumericVar* result) digitbuf_free(result); result->ndigits = res_ndigits; - result->buf = res_buf; - result->digits = res_digits; + if (res_buf != tdig) { + result->buf = res_buf; + result->digits = res_digits; + } else { + result->buf = result->ndb; + result->digits = result->buf; + errno_t rc = memcpy_s(result->buf, sizeof(NumericDigit) * (res_ndigits + 1), + res_buf, sizeof(NumericDigit) * (res_ndigits + 1)); + securec_check(rc, "\0", "\0"); + result->digits ++; + } result->weight = res_weight; result->dscale = res_dscale;