mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Second thoughts dept: arrange to cache mergejoin scan selectivity
in RestrictInfo nodes, instead of recomputing on every use.
This commit is contained in:
		@@ -15,7 +15,7 @@
 | 
			
		||||
 * Portions Copyright (c) 1994, Regents of the University of California
 | 
			
		||||
 *
 | 
			
		||||
 * 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->right_pathkey = NIL;
 | 
			
		||||
	newnode->left_mergescansel = from->left_mergescansel;
 | 
			
		||||
	newnode->right_mergescansel = from->right_mergescansel;
 | 
			
		||||
	newnode->hashjoinoperator = from->hashjoinoperator;
 | 
			
		||||
	newnode->left_bucketsize = from->left_bucketsize;
 | 
			
		||||
	newnode->right_bucketsize = from->right_bucketsize;
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 * 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
 | 
			
		||||
 *	  Most of the read functions for plan nodes are tested. (In fact, they
 | 
			
		||||
@@ -1846,9 +1846,11 @@ _readRestrictInfo(void)
 | 
			
		||||
	local_node->eval_cost = -1;
 | 
			
		||||
	/* ditto for this_selec */
 | 
			
		||||
	local_node->this_selec = -1;
 | 
			
		||||
	/* ditto for cached pathkeys and bucketsize */
 | 
			
		||||
	/* ditto for cached pathkeys, selectivity, bucketsize */
 | 
			
		||||
	local_node->left_pathkey = NIL;
 | 
			
		||||
	local_node->right_pathkey = NIL;
 | 
			
		||||
	local_node->left_mergescansel = -1;
 | 
			
		||||
	local_node->right_mergescansel = -1;
 | 
			
		||||
	local_node->left_bucketsize = -1;
 | 
			
		||||
	local_node->right_bucketsize = -1;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -42,7 +42,7 @@
 | 
			
		||||
 * Portions Copyright (c) 1994, Regents of the University of California
 | 
			
		||||
 *
 | 
			
		||||
 * 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		run_cost = 0;
 | 
			
		||||
	Cost		cpu_per_tuple;
 | 
			
		||||
	RestrictInfo *firstclause;
 | 
			
		||||
	double		outer_rows,
 | 
			
		||||
				inner_rows;
 | 
			
		||||
	double		ntuples;
 | 
			
		||||
@@ -581,10 +582,18 @@ cost_mergejoin(Path *path, Query *root,
 | 
			
		||||
	 * Estimate fraction of the left and right inputs that will actually
 | 
			
		||||
	 * need to be scanned.  We use only the first (most significant)
 | 
			
		||||
	 * 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,
 | 
			
		||||
					 (Node *) ((RestrictInfo *) lfirst(mergeclauses))->clause,
 | 
			
		||||
					 &leftscan, &rightscan);
 | 
			
		||||
	firstclause = (RestrictInfo *) lfirst(mergeclauses);
 | 
			
		||||
	if (firstclause->left_mergescansel < 0)	/* not computed yet? */
 | 
			
		||||
		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;
 | 
			
		||||
	inner_rows = inner_path->parent->rows * rightscan;
 | 
			
		||||
@@ -1099,9 +1108,9 @@ cost_qual_eval_walker(Node *node, Cost *total)
 | 
			
		||||
 * big difference.)
 | 
			
		||||
 *
 | 
			
		||||
 * The "dirty" part comes from the fact that the selectivities of multiple
 | 
			
		||||
 * clauses are estimated independently and multiplied together.  Currently,
 | 
			
		||||
 * clauselist_selectivity can seldom do any better than that anyhow, but
 | 
			
		||||
 * someday it might be smarter.
 | 
			
		||||
 * clauses are estimated independently and multiplied together.  Now
 | 
			
		||||
 * clauselist_selectivity often can't do any better than that anyhow, but
 | 
			
		||||
 * for some situations (such as range constraints) it is smarter.
 | 
			
		||||
 *
 | 
			
		||||
 * Since we are only using the results to estimate how many potential
 | 
			
		||||
 * output tuples are generated and passed through qpqual checking, it
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 * 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->left_pathkey = NIL;	/* not computable yet */
 | 
			
		||||
	restrictinfo->right_pathkey = NIL;
 | 
			
		||||
	restrictinfo->left_mergescansel = -1; /* not computed until needed */
 | 
			
		||||
	restrictinfo->right_mergescansel = -1;
 | 
			
		||||
	restrictinfo->hashjoinoperator = InvalidOid;
 | 
			
		||||
	restrictinfo->left_bucketsize = -1; /* not computed until needed */
 | 
			
		||||
	restrictinfo->right_bucketsize = -1;
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 * 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->left_pathkey = NIL;	/* and these */
 | 
			
		||||
		newinfo->right_pathkey = NIL;
 | 
			
		||||
		newinfo->left_mergescansel = -1;
 | 
			
		||||
		newinfo->right_mergescansel = -1;
 | 
			
		||||
		newinfo->left_bucketsize = -1;
 | 
			
		||||
		newinfo->right_bucketsize = -1;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
 * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
 | 
			
		||||
 * 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	   *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: */
 | 
			
		||||
	Oid			hashjoinoperator;		/* copy of clause operator */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user