Skip to content

Commit 17b843d

Browse files
committed
Cache eval cost of qualification expressions in RestrictInfo nodes to
avoid repeated evaluations in cost_qual_eval(). This turns out to save a useful fraction of planning time. No change to external representation of RestrictInfo --- although that node type doesn't appear in stored rules anyway.
1 parent 77c443f commit 17b843d

File tree

7 files changed

+54
-24
lines changed

7 files changed

+54
-24
lines changed

src/backend/nodes/copyfuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Portions Copyright (c) 1994, Regents of the University of California
1616
*
1717
* IDENTIFICATION
18-
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.133 2000/11/24 20:16:39 petere Exp $
18+
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.134 2000/12/12 23:33:32 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -1418,6 +1418,7 @@ _copyRestrictInfo(RestrictInfo *from)
14181418
* ----------------
14191419
*/
14201420
Node_Copy(from, newnode, clause);
1421+
newnode->eval_cost = from->eval_cost;
14211422
newnode->ispusheddown = from->ispusheddown;
14221423
Node_Copy(from, newnode, subclauseindices);
14231424
newnode->mergejoinoperator = from->mergejoinoperator;

src/backend/nodes/equalfuncs.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* Portions Copyright (c) 1994, Regents of the University of California
2121
*
2222
* IDENTIFICATION
23-
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.83 2000/11/24 20:16:39 petere Exp $
23+
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.84 2000/12/12 23:33:33 tgl Exp $
2424
*
2525
*-------------------------------------------------------------------------
2626
*/
@@ -514,6 +514,10 @@ _equalRestrictInfo(RestrictInfo *a, RestrictInfo *b)
514514
{
515515
if (!equal(a->clause, b->clause))
516516
return false;
517+
/*
518+
* ignore eval_cost, since it may not be set yet, and should be
519+
* derivable from the clause anyway
520+
*/
517521
if (a->ispusheddown != b->ispusheddown)
518522
return false;
519523
if (!equal(a->subclauseindices, b->subclauseindices))

src/backend/nodes/readfuncs.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.100 2000/11/12 00:36:57 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.101 2000/12/12 23:33:33 tgl Exp $
1212
*
1313
* NOTES
1414
* Most of the read functions for plan nodes are tested. (In fact, they
@@ -1846,6 +1846,9 @@ _readRestrictInfo(void)
18461846
token = lsptok(NULL, &length); /* now read it */
18471847
local_node->hashjoinoperator = (Oid) atol(token);
18481848

1849+
/* eval_cost is not part of saved representation; compute on first use */
1850+
local_node->eval_cost = -1;
1851+
18491852
return local_node;
18501853
}
18511854

src/backend/optimizer/path/costsize.c

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
* Portions Copyright (c) 1994, Regents of the University of California
4343
*
4444
* IDENTIFICATION
45-
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.64 2000/10/05 19:48:26 momjian Exp $
45+
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.65 2000/12/12 23:33:33 tgl Exp $
4646
*
4747
*-------------------------------------------------------------------------
4848
*/
@@ -672,8 +672,38 @@ Cost
672672
cost_qual_eval(List *quals)
673673
{
674674
Cost total = 0;
675+
List *l;
675676

676-
cost_qual_eval_walker((Node *) quals, &total);
677+
/* We don't charge any cost for the implicit ANDing at top level ... */
678+
679+
foreach(l, quals)
680+
{
681+
Node *qual = (Node *) lfirst(l);
682+
683+
/*
684+
* RestrictInfo nodes contain an eval_cost field reserved for this
685+
* routine's use, so that it's not necessary to evaluate the qual
686+
* clause's cost more than once. If the clause's cost hasn't been
687+
* computed yet, the field will contain -1.
688+
*/
689+
if (qual && IsA(qual, RestrictInfo))
690+
{
691+
RestrictInfo *restrictinfo = (RestrictInfo *) qual;
692+
693+
if (restrictinfo->eval_cost < 0)
694+
{
695+
restrictinfo->eval_cost = 0;
696+
cost_qual_eval_walker((Node *) restrictinfo->clause,
697+
&restrictinfo->eval_cost);
698+
}
699+
total += restrictinfo->eval_cost;
700+
}
701+
else
702+
{
703+
/* If it's a bare expression, must always do it the hard way */
704+
cost_qual_eval_walker(qual, &total);
705+
}
706+
}
677707
return total;
678708
}
679709

@@ -748,18 +778,6 @@ cost_qual_eval_walker(Node *node, Cost *total)
748778
}
749779
/* fall through to examine args of Expr node */
750780
}
751-
752-
/*
753-
* expression_tree_walker doesn't know what to do with RestrictInfo
754-
* nodes, but we just want to recurse through them.
755-
*/
756-
if (IsA(node, RestrictInfo))
757-
{
758-
RestrictInfo *restrictinfo = (RestrictInfo *) node;
759-
760-
return cost_qual_eval_walker((Node *) restrictinfo->clause, total);
761-
}
762-
/* Otherwise, recurse. */
763781
return expression_tree_walker(node, cost_qual_eval_walker,
764782
(void *) total);
765783
}

src/backend/optimizer/plan/initsplan.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.53 2000/11/23 03:57:31 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.54 2000/12/12 23:33:33 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -338,6 +338,7 @@ distribute_qual_to_rels(Query *root, Node *clause,
338338
bool can_be_equijoin;
339339

340340
restrictinfo->clause = (Expr *) clause;
341+
restrictinfo->eval_cost = -1; /* not computed until needed */
341342
restrictinfo->subclauseindices = NIL;
342343
restrictinfo->mergejoinoperator = InvalidOid;
343344
restrictinfo->left_sortop = InvalidOid;

src/backend/optimizer/prep/prepunion.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
*
1515
*
1616
* IDENTIFICATION
17-
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.56 2000/11/12 00:36:59 tgl Exp $
17+
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.57 2000/12/12 23:33:34 tgl Exp $
1818
*
1919
*-------------------------------------------------------------------------
2020
*/
@@ -652,7 +652,7 @@ adjust_inherited_attrs_mutator(Node *node,
652652
/*
653653
* We have to process RestrictInfo nodes specially: we do NOT want to
654654
* copy the original subclauseindices list, since the new rel may have
655-
* different indices. The list will be rebuilt during planning anyway.
655+
* different indices. The list will be rebuilt during later planning.
656656
*/
657657
if (IsA(node, RestrictInfo))
658658
{
@@ -666,6 +666,7 @@ adjust_inherited_attrs_mutator(Node *node,
666666
adjust_inherited_attrs_mutator((Node *) oldinfo->clause, context);
667667

668668
newinfo->subclauseindices = NIL;
669+
newinfo->eval_cost = -1; /* reset this too */
669670

670671
return (Node *) newinfo;
671672
}

src/include/nodes/relation.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: relation.h,v 1.50 2000/11/12 00:37:01 tgl Exp $
10+
* $Id: relation.h,v 1.51 2000/12/12 23:33:32 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -373,9 +373,9 @@ typedef JoinPath NestPath;
373373
* A mergejoin path has these fields.
374374
*
375375
* path_mergeclauses lists the clauses (in the form of RestrictInfos)
376-
* that will be used in the merge. (Before 7.0, this was a list of
377-
* bare clause expressions, but we can save on list memory by leaving
378-
* it in the form of a RestrictInfo list.)
376+
* that will be used in the merge. (Before 7.0, this was a list of bare
377+
* clause expressions, but we can save on list memory and cost_qual_eval
378+
* work by leaving it in the form of a RestrictInfo list.)
379379
*
380380
* Note that the mergeclauses are a subset of the parent relation's
381381
* restriction-clause list. Any join clauses that are not mergejoinable
@@ -491,6 +491,8 @@ typedef struct RestrictInfo
491491

492492
Expr *clause; /* the represented clause of WHERE or JOIN */
493493

494+
Cost eval_cost; /* eval cost of clause; -1 if not yet set */
495+
494496
bool ispusheddown; /* TRUE if clause was pushed down in level */
495497

496498
/* only used if clause is an OR clause: */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy