Second thoughts dept: arrange to cache mergejoin scan selectivity
in RestrictInfo nodes, instead of recomputing on every use.
This commit is contained in:
parent
f8c109528c
commit
8f0a9e85b3
@ -15,7 +15,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.163 2002/02/26 22:47:05 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.164 2002/03/01 06:01:18 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1406,6 +1406,8 @@ _copyRestrictInfo(RestrictInfo *from)
|
|||||||
*/
|
*/
|
||||||
newnode->left_pathkey = NIL;
|
newnode->left_pathkey = NIL;
|
||||||
newnode->right_pathkey = NIL;
|
newnode->right_pathkey = NIL;
|
||||||
|
newnode->left_mergescansel = from->left_mergescansel;
|
||||||
|
newnode->right_mergescansel = from->right_mergescansel;
|
||||||
newnode->hashjoinoperator = from->hashjoinoperator;
|
newnode->hashjoinoperator = from->hashjoinoperator;
|
||||||
newnode->left_bucketsize = from->left_bucketsize;
|
newnode->left_bucketsize = from->left_bucketsize;
|
||||||
newnode->right_bucketsize = from->right_bucketsize;
|
newnode->right_bucketsize = from->right_bucketsize;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.114 2002/02/26 22:47:07 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.115 2002/03/01 06:01:18 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Most of the read functions for plan nodes are tested. (In fact, they
|
* Most of the read functions for plan nodes are tested. (In fact, they
|
||||||
@ -1846,9 +1846,11 @@ _readRestrictInfo(void)
|
|||||||
local_node->eval_cost = -1;
|
local_node->eval_cost = -1;
|
||||||
/* ditto for this_selec */
|
/* ditto for this_selec */
|
||||||
local_node->this_selec = -1;
|
local_node->this_selec = -1;
|
||||||
/* ditto for cached pathkeys and bucketsize */
|
/* ditto for cached pathkeys, selectivity, bucketsize */
|
||||||
local_node->left_pathkey = NIL;
|
local_node->left_pathkey = NIL;
|
||||||
local_node->right_pathkey = NIL;
|
local_node->right_pathkey = NIL;
|
||||||
|
local_node->left_mergescansel = -1;
|
||||||
|
local_node->right_mergescansel = -1;
|
||||||
local_node->left_bucketsize = -1;
|
local_node->left_bucketsize = -1;
|
||||||
local_node->right_bucketsize = -1;
|
local_node->right_bucketsize = -1;
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.80 2002/03/01 04:09:24 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.81 2002/03/01 06:01:19 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -566,6 +566,7 @@ cost_mergejoin(Path *path, Query *root,
|
|||||||
Cost startup_cost = 0;
|
Cost startup_cost = 0;
|
||||||
Cost run_cost = 0;
|
Cost run_cost = 0;
|
||||||
Cost cpu_per_tuple;
|
Cost cpu_per_tuple;
|
||||||
|
RestrictInfo *firstclause;
|
||||||
double outer_rows,
|
double outer_rows,
|
||||||
inner_rows;
|
inner_rows;
|
||||||
double ntuples;
|
double ntuples;
|
||||||
@ -581,10 +582,18 @@ cost_mergejoin(Path *path, Query *root,
|
|||||||
* Estimate fraction of the left and right inputs that will actually
|
* Estimate fraction of the left and right inputs that will actually
|
||||||
* need to be scanned. We use only the first (most significant)
|
* need to be scanned. We use only the first (most significant)
|
||||||
* merge clause for this purpose.
|
* merge clause for this purpose.
|
||||||
|
*
|
||||||
|
* Since this calculation is somewhat expensive, and will be the same
|
||||||
|
* for all mergejoin paths associated with the merge clause, we cache
|
||||||
|
* the results in the RestrictInfo node.
|
||||||
*/
|
*/
|
||||||
mergejoinscansel(root,
|
firstclause = (RestrictInfo *) lfirst(mergeclauses);
|
||||||
(Node *) ((RestrictInfo *) lfirst(mergeclauses))->clause,
|
if (firstclause->left_mergescansel < 0) /* not computed yet? */
|
||||||
&leftscan, &rightscan);
|
mergejoinscansel(root, (Node *) firstclause->clause,
|
||||||
|
&firstclause->left_mergescansel,
|
||||||
|
&firstclause->right_mergescansel);
|
||||||
|
leftscan = firstclause->left_mergescansel;
|
||||||
|
rightscan = firstclause->right_mergescansel;
|
||||||
|
|
||||||
outer_rows = outer_path->parent->rows * leftscan;
|
outer_rows = outer_path->parent->rows * leftscan;
|
||||||
inner_rows = inner_path->parent->rows * rightscan;
|
inner_rows = inner_path->parent->rows * rightscan;
|
||||||
@ -1099,9 +1108,9 @@ cost_qual_eval_walker(Node *node, Cost *total)
|
|||||||
* big difference.)
|
* big difference.)
|
||||||
*
|
*
|
||||||
* The "dirty" part comes from the fact that the selectivities of multiple
|
* The "dirty" part comes from the fact that the selectivities of multiple
|
||||||
* clauses are estimated independently and multiplied together. Currently,
|
* clauses are estimated independently and multiplied together. Now
|
||||||
* clauselist_selectivity can seldom do any better than that anyhow, but
|
* clauselist_selectivity often can't do any better than that anyhow, but
|
||||||
* someday it might be smarter.
|
* for some situations (such as range constraints) it is smarter.
|
||||||
*
|
*
|
||||||
* Since we are only using the results to estimate how many potential
|
* Since we are only using the results to estimate how many potential
|
||||||
* output tuples are generated and passed through qpqual checking, it
|
* output tuples are generated and passed through qpqual checking, it
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.65 2001/10/25 05:49:33 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.66 2002/03/01 06:01:19 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -370,6 +370,8 @@ distribute_qual_to_rels(Query *root, Node *clause,
|
|||||||
restrictinfo->right_sortop = InvalidOid;
|
restrictinfo->right_sortop = InvalidOid;
|
||||||
restrictinfo->left_pathkey = NIL; /* not computable yet */
|
restrictinfo->left_pathkey = NIL; /* not computable yet */
|
||||||
restrictinfo->right_pathkey = NIL;
|
restrictinfo->right_pathkey = NIL;
|
||||||
|
restrictinfo->left_mergescansel = -1; /* not computed until needed */
|
||||||
|
restrictinfo->right_mergescansel = -1;
|
||||||
restrictinfo->hashjoinoperator = InvalidOid;
|
restrictinfo->hashjoinoperator = InvalidOid;
|
||||||
restrictinfo->left_bucketsize = -1; /* not computed until needed */
|
restrictinfo->left_bucketsize = -1; /* not computed until needed */
|
||||||
restrictinfo->right_bucketsize = -1;
|
restrictinfo->right_bucketsize = -1;
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.69 2001/11/12 20:04:20 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.70 2002/03/01 06:01:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -777,6 +777,8 @@ adjust_inherited_attrs_mutator(Node *node,
|
|||||||
newinfo->this_selec = -1;
|
newinfo->this_selec = -1;
|
||||||
newinfo->left_pathkey = NIL; /* and these */
|
newinfo->left_pathkey = NIL; /* and these */
|
||||||
newinfo->right_pathkey = NIL;
|
newinfo->right_pathkey = NIL;
|
||||||
|
newinfo->left_mergescansel = -1;
|
||||||
|
newinfo->right_mergescansel = -1;
|
||||||
newinfo->left_bucketsize = -1;
|
newinfo->left_bucketsize = -1;
|
||||||
newinfo->right_bucketsize = -1;
|
newinfo->right_bucketsize = -1;
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: relation.h,v 1.61 2001/11/05 17:46:34 momjian Exp $
|
* $Id: relation.h,v 1.62 2002/03/01 06:01:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -521,6 +521,10 @@ typedef struct RestrictInfo
|
|||||||
List *left_pathkey; /* canonical pathkey for left side */
|
List *left_pathkey; /* canonical pathkey for left side */
|
||||||
List *right_pathkey; /* canonical pathkey for right side */
|
List *right_pathkey; /* canonical pathkey for right side */
|
||||||
|
|
||||||
|
/* cache space for mergeclause processing; -1 if not yet set */
|
||||||
|
Selectivity left_mergescansel; /* fraction of left side to scan */
|
||||||
|
Selectivity right_mergescansel; /* fraction of right side to scan */
|
||||||
|
|
||||||
/* valid if clause is hashjoinable, else InvalidOid: */
|
/* valid if clause is hashjoinable, else InvalidOid: */
|
||||||
Oid hashjoinoperator; /* copy of clause operator */
|
Oid hashjoinoperator; /* copy of clause operator */
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user