From f8a9e0c3f9102b1457cd3551f912afe6d42b9949 Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Tue, 21 Jan 2020 17:52:08 +1300 Subject: [PATCH] Avoid unnecessary shmem writes in Parallel Hash Join. Currently, Parallel Hash Join cannot be used for full/right joins, so there is no point in setting the match flag. It turns out that the cache coherence traffic generated by those writes slows down large systems running many-core joins, so let's stop doing that. In future, if we need to use match bits in parallel joins, we might want to consider setting them only if not already set. Back-patch to 11, where PHJ arrived. Reported-by: Deng, Gang Discussion: https://postgr.es/m/0F44E799048C4849BAE4B91012DB910462E9897A%40SHSMSX103.ccr.corp.intel.com --- src/backend/executor/nodeHashjoin.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c index 67c717910f..c901a80923 100644 --- a/src/backend/executor/nodeHashjoin.c +++ b/src/backend/executor/nodeHashjoin.c @@ -454,7 +454,26 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel) if (joinqual == NULL || ExecQual(joinqual, econtext)) { node->hj_MatchedOuter = true; - HeapTupleHeaderSetMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple)); + + if (parallel) + { + /* + * Full/right outer joins are currently not supported + * for parallel joins, so we don't need to set the + * match bit. Experiments show that it's worth + * avoiding the shared memory traffic on large + * systems. + */ + Assert(!HJ_FILL_INNER(node)); + } + else + { + /* + * This is really only needed if HJ_FILL_INNER(node), + * but we'll avoid the branch and just set it always. + */ + HeapTupleHeaderSetMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple)); + } /* In an antijoin, we never return a matched tuple */ if (node->js.jointype == JOIN_ANTI) -- 2.24.1