1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-13 07:41:39 +03:00

Improve hash join to discard input tuples immediately if they can't

match because they contain a null join key (and the join operator is
known strict).  Improves performance significantly when the inner
relation contains a lot of nulls, as per bug #2930.
This commit is contained in:
Tom Lane
2007-01-28 23:21:26 +00:00
parent 28c480e9ae
commit b39e91501c
4 changed files with 70 additions and 25 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/nodeHashjoin.c,v 1.86 2007/01/05 22:19:28 momjian Exp $
* $PostgreSQL: pgsql/src/backend/executor/nodeHashjoin.c,v 1.87 2007/01/28 23:21:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -547,9 +547,8 @@ ExecHashJoinOuterGetTuple(PlanState *outerNode,
int curbatch = hashtable->curbatch;
TupleTableSlot *slot;
if (curbatch == 0)
{ /* if it is the first pass */
if (curbatch == 0) /* if it is the first pass */
{
/*
* Check to see if first outer tuple was already fetched by
* ExecHashJoin() and not used yet.
@ -559,7 +558,8 @@ ExecHashJoinOuterGetTuple(PlanState *outerNode,
hjstate->hj_FirstOuterTupleSlot = NULL;
else
slot = ExecProcNode(outerNode);
if (!TupIsNull(slot))
while (!TupIsNull(slot))
{
/*
* We have to compute the tuple's hash value.
@ -567,13 +567,22 @@ ExecHashJoinOuterGetTuple(PlanState *outerNode,
ExprContext *econtext = hjstate->js.ps.ps_ExprContext;
econtext->ecxt_outertuple = slot;
*hashvalue = ExecHashGetHashValue(hashtable, econtext,
hjstate->hj_OuterHashKeys);
if (ExecHashGetHashValue(hashtable, econtext,
hjstate->hj_OuterHashKeys,
(hjstate->js.jointype == JOIN_LEFT),
hashvalue))
{
/* remember outer relation is not empty for possible rescan */
hjstate->hj_OuterNotEmpty = true;
/* remember outer relation is not empty for possible rescan */
hjstate->hj_OuterNotEmpty = true;
return slot;
}
return slot;
/*
* That tuple couldn't match because of a NULL, so discard it
* and continue with the next one.
*/
slot = ExecProcNode(outerNode);
}
/*