From 36a4c6248bd4eec9062ed477b7c3f551738e3c96 Mon Sep 17 00:00:00 2001 From: junhangis Date: Sun, 7 Aug 2022 02:11:01 +0800 Subject: [PATCH] improve the performance of numeric subtraction. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit before optimization£º openGauss=# explain analyse select t0 - t1 from t_numeric limit 10000000; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ Limit (cost=0.00..292129.20 rows=8468656 width=10) (actual time=4.688..11066.444 rows=8388608 loops=1) -> Seq Scan on t_numeric (cost=0.00..292129.20 rows=8468656 width=10) (actual time=4.686..9901.704 rows=8388608 loops=1) Total runtime: 12103.123 ms (3 rows) Time: 12106.419 ms after optimization£º openGauss=# explain analyse select t0 - t1 from t_numeric limit 10000000; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ Limit (cost=0.00..292129.20 rows=8468656 width=10) (actual time=4.182..9914.114 rows=8388608 loops=1) -> Seq Scan on t_numeric (cost=0.00..292129.20 rows=8468656 width=10) (actual time=4.180..8732.662 rows=8388608 loops=1) Total runtime: 10918.849 ms (3 rows) Time: 10919.690 ms --- src/common/backend/utils/adt/numeric.cpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/common/backend/utils/adt/numeric.cpp b/src/common/backend/utils/adt/numeric.cpp index 59a6890be..58c9cb255 100644 --- a/src/common/backend/utils/adt/numeric.cpp +++ b/src/common/backend/utils/adt/numeric.cpp @@ -2174,7 +2174,7 @@ Datum numeric_sub(PG_FUNCTION_ARGS) init_var_from_num(num1, &arg1); init_var_from_num(num2, &arg2); - init_var(&result); + quick_init_var(&result); sub_var(&arg1, &arg2, &result); res = make_result(&result); @@ -6705,6 +6705,7 @@ static void sub_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 = var1->weight; @@ -6720,7 +6721,10 @@ static void sub_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; @@ -6747,8 +6751,18 @@ static void sub_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;