diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2007-01-28 23:21:26 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2007-01-28 23:21:26 +0000 |
commit | b39e91501c101d67b92f3e6965da5dc111195f52 (patch) | |
tree | 1820d8ba0289c5e32a025b9f62bdd98ca494a972 /src/backend/executor/nodeHashjoin.c | |
parent | 28c480e9ae64fc239fa1ebe32a981312e65ae1e7 (diff) | |
download | postgresql-b39e91501c101d67b92f3e6965da5dc111195f52.tar.gz postgresql-b39e91501c101d67b92f3e6965da5dc111195f52.zip |
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.
Diffstat (limited to 'src/backend/executor/nodeHashjoin.c')
-rw-r--r-- | src/backend/executor/nodeHashjoin.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c index 7f0801c69bd..b03086fb364 100644 --- a/src/backend/executor/nodeHashjoin.c +++ b/src/backend/executor/nodeHashjoin.c @@ -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); } /* |