From 356687bd825e5ca7230d43c1bffe7a59ad2e77bd Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Sat, 9 Feb 2019 00:35:57 -0800 Subject: Reset, not recreate, execGrouping.c style hashtables. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This uses the facility added in the preceding commit to fix performance issues caused by rebuilding the hashtable (with its comparator expression being the most expensive bit), after every reset. That's especially important when the comparator is JIT compiled. Bug: #15592 #15486 Reported-By: Jakub Janeček, Dmitry Marakasov Author: Andres Freund Discussion: https://postgr.es/m/15486-05850f065da42931@postgresql.org https://postgr.es/m/20190114180423.ywhdg2iagzvh43we@alap3.anarazel.de Backpatch: 11, where I broke this in bf6c614a2f2c5 --- src/backend/executor/nodeSubplan.c | 57 ++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 24 deletions(-) (limited to 'src/backend/executor/nodeSubplan.c') diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c index 152696035cd..d7d076758c3 100644 --- a/src/backend/executor/nodeSubplan.c +++ b/src/backend/executor/nodeSubplan.c @@ -481,8 +481,8 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext) Assert(subplan->subLinkType == ANY_SUBLINK); /* - * If we already had any hash tables, destroy 'em; then create empty hash - * table(s). + * If we already had any hash tables, reset 'em; otherwise create empty + * hash table(s). * * If we need to distinguish accurately between FALSE and UNKNOWN (i.e., * NULL) results of the IN operation, then we have to store subplan output @@ -505,17 +505,21 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext) if (nbuckets < 1) nbuckets = 1; - node->hashtable = BuildTupleHashTable(node->parent, - node->descRight, - ncols, - node->keyColIdx, - node->tab_eq_funcoids, - node->tab_hash_funcs, - nbuckets, - 0, - node->hashtablecxt, - node->hashtempcxt, - false); + if (node->hashtable) + ResetTupleHashTable(node->hashtable); + else + node->hashtable = BuildTupleHashTableExt(node->parent, + node->descRight, + ncols, + node->keyColIdx, + node->tab_eq_funcoids, + node->tab_hash_funcs, + nbuckets, + 0, + node->planstate->state->es_query_cxt, + node->hashtablecxt, + node->hashtempcxt, + false); if (!subplan->unknownEqFalse) { @@ -527,17 +531,22 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext) if (nbuckets < 1) nbuckets = 1; } - node->hashnulls = BuildTupleHashTable(node->parent, - node->descRight, - ncols, - node->keyColIdx, - node->tab_eq_funcoids, - node->tab_hash_funcs, - nbuckets, - 0, - node->hashtablecxt, - node->hashtempcxt, - false); + + if (node->hashnulls) + ResetTupleHashTable(node->hashtable); + else + node->hashnulls = BuildTupleHashTableExt(node->parent, + node->descRight, + ncols, + node->keyColIdx, + node->tab_eq_funcoids, + node->tab_hash_funcs, + nbuckets, + 0, + node->planstate->state->es_query_cxt, + node->hashtablecxt, + node->hashtempcxt, + false); } /* -- cgit v1.2.3