On 19/2/2024 20:47, Tomas Vondra wrote:
On 9/8/23 07:11, Lepikhov Andrei wrote:
Just for comparison, without partitioning:
elems   1               1E1             1E2             1E3             1E4     
master: 12kB    14kB    37kB    266kB   2.5MB
patched:        12kB    11.5kB  13kB    24kB    141kB


These improvements look pretty nice, considering how simple the patch
seems to be. I can't even imagine how much memory we'd need with even
more partitions (say, 1000) if 100 partitions means 274MB.

BTW when releasing memory in scalararraysel, wouldn't it be good to also
free the elem_values/elem_nulls? I haven't tried and maybe it's not that
significant amount.
Agree. Added into the next version of the patch.
Moreover, I see a slight planning speedup. Looking into the reason for that, I discovered that it is because sometimes the planner utilizes the same memory piece for the next array element. It finds this piece more quickly than before that optimization.

--
regards,
Andrei Lepikhov
Postgres Professional
From 2e89dc8b743953068174c777d7a014e1ea71f659 Mon Sep 17 00:00:00 2001
From: "Andrey V. Lepikhov" <a.lepik...@postgrespro.ru>
Date: Tue, 20 Feb 2024 11:05:51 +0700
Subject: [PATCH] Utilize memory in scalararraysel in more optimal manner.

Estimating selectivity on an array operation free the memory right after
working out a single element. It reduces peak memory consumption
on massive arrays.
---
 src/backend/utils/adt/selfuncs.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index cea777e9d4..e5bad75ec1 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -281,6 +281,7 @@ eqsel_internal(PG_FUNCTION_ARGS, bool negate)
                selec = var_eq_non_const(&vardata, operator, collation, other,
                                                                 varonleft, 
negate);
 
+       pfree(other);
        ReleaseVariableStats(vardata);
 
        return selec;
@@ -1961,15 +1962,15 @@ scalararraysel(PlannerInfo *root,
                {
                        List       *args;
                        Selectivity s2;
-
-                       args = list_make2(leftop,
-                                                         
makeConst(nominal_element_type,
-                                                                               
-1,
-                                                                               
nominal_element_collation,
-                                                                               
elmlen,
-                                                                               
elem_values[i],
-                                                                               
elem_nulls[i],
-                                                                               
elmbyval));
+                       Const *c = makeConst(nominal_element_type,
+                                                               -1,
+                                                               
nominal_element_collation,
+                                                               elmlen,
+                                                               elem_values[i],
+                                                               elem_nulls[i],
+                                                               elmbyval);
+
+                       args = list_make2(leftop, c);
                        if (is_join_clause)
                                s2 = 
DatumGetFloat8(FunctionCall5Coll(&oprselproc,
                                                                                
                          clause->inputcollid,
@@ -1985,7 +1986,8 @@ scalararraysel(PlannerInfo *root,
                                                                                
                          ObjectIdGetDatum(operator),
                                                                                
                          PointerGetDatum(args),
                                                                                
                          Int32GetDatum(varRelid)));
-
+                       list_free(args);
+                       pfree(c);
                        if (useOr)
                        {
                                s1 = s1 + s2 - s1 * s2;
@@ -2004,6 +2006,9 @@ scalararraysel(PlannerInfo *root,
                if ((useOr ? isEquality : isInequality) &&
                        s1disjoint >= 0.0 && s1disjoint <= 1.0)
                        s1 = s1disjoint;
+
+               pfree(elem_values);
+               pfree(elem_nulls);
        }
        else if (rightop && IsA(rightop, ArrayExpr) &&
                         !((ArrayExpr *) rightop)->multidims)
@@ -2052,6 +2057,7 @@ scalararraysel(PlannerInfo *root,
                                                                                
                          ObjectIdGetDatum(operator),
                                                                                
                          PointerGetDatum(args),
                                                                                
                          Int32GetDatum(varRelid)));
+                       list_free(args);
 
                        if (useOr)
                        {
-- 
2.43.0

Reply via email to