⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 frombasetable.java

📁 derby database source code.good for you.
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
			}			if (seenFirstColumn && statisticsForConglomerate &&				(startStopPredCount > 0))			{				statStartStopSelectivity = 					tableDescriptor.selectivityForConglomerate(cd, startStopPredCount);			}			/*			** Factor the non-base-table predicates into the extra			** non-qualifier selectivity, since these will restrict the			** number of rows, but not the cost.			*/			extraNonQualifierSelectivity *=				currentJoinStrategy.nonBasePredicateSelectivity(this, predList);			/* Create the start and stop key arrays, and fill them in */			DataValueDescriptor[] startKeys;			DataValueDescriptor[] stopKeys;			if (startKeyNum > 0)				startKeys = new DataValueDescriptor[startKeyNum];			else				startKeys = null;			if (stopKeyNum > 0)				stopKeys = new DataValueDescriptor[stopKeyNum];			else				stopKeys = null;			startKeyNum = 0;			stopKeyNum = 0;			startGap = false;			stopGap = false;			for (int i = 0; i < predListSize; i++)			{				pred = baseTableRestrictionList.getOptPredicate(i);				boolean startKey = pred.isStartKey();				boolean stopKey = pred.isStopKey();				if (startKey || stopKey)				{					boolean knownConstant = pred.compareWithKnownConstant(this, true);					if (startKey)					{						if (knownConstant && ( ! startGap ) )						{							startKeys[startKeyNum] = pred.getCompareValue(this);							startKeyNum++;						}						else						{							startGap = true;						}					}					if (stopKey)					{						if (knownConstant && ( ! stopGap ) )						{							stopKeys[stopKeyNum] = pred.getCompareValue(this);							stopKeyNum++;						}						else						{							stopGap = true;						}					}				}				else				{					startGap = true;					stopGap = true;				}			}			int startOperator;			int stopOperator;			if (baseTableRestrictionList != null)			{				startOperator = baseTableRestrictionList.startOperator(this);				stopOperator = baseTableRestrictionList.stopOperator(this);			}			else			{				/*				** If we're doing a full scan, it doesn't matter what the				** start and stop operators are.				*/				startOperator = ScanController.NA;				stopOperator = ScanController.NA;			}			/*			** Get a row template for this conglomerate.  For now, just tell			** it we are using all the columns in the row.			*/			DataValueDescriptor[] rowTemplate =                 getRowTemplate(cd, getBaseCostController());			/* we prefer index than table scan for concurrency reason, by a small			 * adjustment on estimated row count.  This affects optimizer's decision			 * especially when few rows are in table. beetle 5006. This makes sense			 * since the plan may stay long before we actually check and invalidate it.			 * And new rows may be inserted before we check and invalidate the plan.			 * Here we only prefer index that has start/stop key from predicates. Non-			 * constant start/stop key case is taken care of by selectivity later.			 */			long baseRC = (startKeys != null || stopKeys != null) ? baseRowCount() : baseRowCount() + 5;			scc.getScanCost(					currentJoinStrategy.scanCostType(),					baseRC,                    1,					forUpdate(),					(FormatableBitSet) null,					rowTemplate,					startKeys,					startOperator,					stopKeys,					stopOperator,					false,					0,					costEstimate);			/* initialPositionCost is the first part of the index scan cost we get above.			 * It's the cost of initial positioning/fetch of key.  So it's unrelated to			 * row count of how many rows we fetch from index.  We extract it here so that			 * we only multiply selectivity to the other part of index scan cost, which is			 * nearly linear, to make cost calculation more accurate and fair, especially			 * compared to the plan of "one row result set" (unique index). beetle 4787.			 */			double initialPositionCost = 0.0;			if (cd.isIndex())			{				initialPositionCost = scc.getFetchFromFullKeyCost((FormatableBitSet) null, 0);				/* oneRowResultSetForSomeConglom means there's a unique index, but certainly				 * not this one since we are here.  If store knows this non-unique index				 * won't return any row or just returns one row (eg., the predicate is a				 * comparison with constant or almost empty table), we do minor adjustment				 * on cost (affecting decision for covering index) and rc (decision for				 * non-covering). The purpose is favoring unique index. beetle 5006.				 */				if (oneRowResultSetForSomeConglom && costEstimate.rowCount() <= 1)				{					costEstimate.setCost(costEstimate.getEstimatedCost() * 2,										 costEstimate.rowCount() + 2,										 costEstimate.singleScanRowCount() + 2);				}			}			optimizer.trace(Optimizer.COST_OF_CONGLOMERATE_SCAN1,							tableNumber, 0, 0.0, cd);			optimizer.trace(Optimizer.COST_OF_CONGLOMERATE_SCAN2,							tableNumber, 0, 0.0, costEstimate);			optimizer.trace(Optimizer.COST_OF_CONGLOMERATE_SCAN3,							numExtraFirstColumnPreds, 0, 							extraFirstColumnSelectivity, null);			optimizer.trace(Optimizer.COST_OF_CONGLOMERATE_SCAN4,							numExtraStartStopPreds, 0, 							extraStartStopSelectivity, null);			optimizer.trace(Optimizer.COST_OF_CONGLOMERATE_SCAN7,							startStopPredCount, 0,							statStartStopSelectivity, null);			optimizer.trace(Optimizer.COST_OF_CONGLOMERATE_SCAN5,							numExtraQualifiers, 0, 							extraQualifierSelectivity, null);			optimizer.trace(Optimizer.COST_OF_CONGLOMERATE_SCAN6,							numExtraNonQualifiers, 0, 							extraNonQualifierSelectivity, null);			/* initial row count is the row count without applying			   any predicates-- we use this at the end of the routine			   when we use statistics to recompute the row count.			*/			double initialRowCount = costEstimate.rowCount();			if (statStartStopSelectivity != 1.0d)			{				/*				** If statistics exist use the selectivity computed 				** from the statistics to calculate the cost. 				** NOTE: we apply this selectivity to the cost as well				** as both the row counts. In the absence of statistics				** we only applied the FirstColumnSelectivity to the 				** cost.				*/				costEstimate.setCost(							 scanCostAfterSelectivity(costEstimate.getEstimatedCost(),													  initialPositionCost,													  statStartStopSelectivity,													  oneRowResultSetForSomeConglom),							 costEstimate.rowCount() * statStartStopSelectivity,							 costEstimate.singleScanRowCount() *							 statStartStopSelectivity);				optimizer.trace(Optimizer.COST_INCLUDING_STATS_FOR_INDEX,								tableNumber, 0, 0.0, costEstimate);			}			else			{				/*				** Factor in the extra selectivity on the first column				** of the conglomerate (see comment above).				** NOTE: In this case we want to apply the selectivity to both				** the total row count and singleScanRowCount.				*/				if (extraFirstColumnSelectivity != 1.0d)				{					costEstimate.setCost(						 scanCostAfterSelectivity(costEstimate.getEstimatedCost(),												  initialPositionCost,												  extraFirstColumnSelectivity,												  oneRowResultSetForSomeConglom),						 costEstimate.rowCount() * extraFirstColumnSelectivity,						 costEstimate.singleScanRowCount() * extraFirstColumnSelectivity);										optimizer.trace(Optimizer.COST_INCLUDING_EXTRA_1ST_COL_SELECTIVITY,									tableNumber, 0, 0.0, costEstimate);				}				/* Factor in the extra start/stop selectivity (see comment above).				 * NOTE: In this case we want to apply the selectivity to both				 * the row count and singleScanRowCount.				 */				if (extraStartStopSelectivity != 1.0d)				{					costEstimate.setCost(						costEstimate.getEstimatedCost(),						costEstimate.rowCount() * extraStartStopSelectivity,						costEstimate.singleScanRowCount() * extraStartStopSelectivity);					optimizer.trace(Optimizer.COST_INCLUDING_EXTRA_START_STOP,									tableNumber, 0, 0.0, costEstimate);				}			}			/*			** Figure out whether to do row locking or table locking.			**			** If there are no start/stop predicates, we're doing full			** conglomerate scans, so do table locking.			*/			if (! startStopFound)			{				currentAccessPath.setLockMode(											TransactionController.MODE_TABLE);				optimizer.trace(Optimizer.TABLE_LOCK_NO_START_STOP,							    0, 0, 0.0, null);			}			else			{				/*				** Figure out the number of rows touched.  If all the				** start/stop predicates are constant, the number of				** rows touched is the number of rows per scan.				** This is also true for join strategies that scan the				** inner table only once (like hash join) - we can				** tell if we have one of those, because				** multiplyBaseCostByOuterRows() will return false.				*/				double rowsTouched = costEstimate.rowCount();				if ( (! constantStartStop) &&					 currentJoinStrategy.multiplyBaseCostByOuterRows())				{					/*					** This is a join where the inner table is scanned					** more than once, so we have to take the number					** of outer rows into account.  The formula for this					** works out as follows:					**					**	total rows in table = r					**  number of rows touched per scan = s					**  number of outer rows = o					**  proportion of rows touched per scan = s / r					**  proportion of rows not touched per scan =					**										1 - (s / r)					**  proportion of rows not touched for all scans =					**									(1 - (s / r)) ** o					**  proportion of rows touched for all scans =					**									1 - ((1 - (s / r)) ** o)					**  total rows touched for all scans =					**							r * (1 - ((1 - (s / r)) ** o))					**					** In doing these calculations, we must be careful not					** to divide by zero.  This could happen if there are					** no rows in the table.  In this case, let's do table					** locking.					*/					double r = baseRowCount();					if (r > 0.0)					{						double s = costEstimate.rowCount();						double o = outerCost.rowCount();						double pRowsNotTouchedPerScan = 1.0 - (s / r);						double pRowsNotTouchedAllScans =										Math.pow(pRowsNotTouchedPerScan, o);						double pRowsTouchedAllScans =										1.0 - pRowsNotTouchedAllScans;						double rowsTouchedAllScans =										r * pRowsTouchedAllScans;						rowsTouched = rowsTouchedAllScans;					}					else					{						/* See comments in setLockingBasedOnThreshold */						rowsTouched = optimizer.tableLockThreshold() + 1;					}				}				setLockingBasedOnThreshold(optimizer, rowsTouched);			}			/*			** If the index isn't covering, add the cost of getting the			** base row.  Only apply extraFirstColumnSelectivity and extraStartStopSelectivity			** before we do this, don't apply extraQualifierSelectivity etc.  The			** reason is that the row count here should be the number of index rows			** (and hence heap rows) we get, and we need to fetch all those rows, even			** though later on some of them may be filtered out by other predicates.			** beetle 4787.			*/			if (cd.isIndex() && ( ! isCoveringIndex(cd) ) )			{				double singleFetchCost =						getBaseCostController().getFetchFromRowLocationCost(																(FormatableBitSet) null,																0);				cost = singleFetchCost * costEstimate.rowCount();				costEstimate.setEstimatedCost(								costEstimate.getEstimatedCost() + cost);				optimizer.trace(Optimizer.COST_OF_NONCOVERING_INDEX,								tableNumber, 0, 0.0, costEstimate);			}			/* Factor in the extra qualifier selectivity (see comment above).			 * NOTE: In this case we want to apply the selectivity to both			 * the row count and singleScanRowCount.			 */			if (extraQualifierSelectivity != 1.0d)			{				costEstimate.setCost(						costEstimate.getEstimatedCost(),						costEstimate.rowCount() * extraQualifierSelectivity,						costEstimate.singleScanRowCount() * extraQualifierSelectivity);				optimizer.trace(Optimizer.COST_INCLUDING_EXTRA_QUALIFIER_SELECTIVITY,								tableNumber, 0, 0.0, costEstimate);			}			singleScanRowCount = costEstimate.singleScanRowCount();			/*			** Let the join strategy decide whether the cost of the base			** scan is a single scan, or a scan per outer row.			** NOTE: In this case we only want to multiply against the			** total row count, not the singleScanRowCount.			** NOTE: Do not multiply row count if we determined that			** conglomerate is a 1 row result set when costing nested			** loop.  (eg, we will find at most 1 match when probing			** the hash table.)			*/			double newCost = costEstimate.getEstimatedCost();			double rowCount = costEstimate.rowCount();			/*			** RESOLVE - If there is a unique index on the joining			** columns, the number of matching rows will equal the			** number of outer rows, even if we're not considering the			** unique index for this access path. To figure that out,			** however, would require an analysis phase at the beginning			** of optimization. So, we'll always multiply the number			** of outer rows by the number of rows per scan. This will			** give us a higher than actual row count when there is			** such a unique index, which will bias the optimizer toward			** using the unique index. This is probably OK most of the			** time, since the optimizer would probably choose the			** unique index, anyway. But it would be better if the			** optimizer set the row count properly in this case.			*/			if (currentJoinStrategy.multiplyBaseCostByOuterRows())			{				newCost *= outerCost.rowCount();			}			rowCount *= outerCost.rowCount();			initialRowCount *= outerCost.rowCount();			/*			** If this table can generate at most one row per scan,			** the maximum row count is the number of outer rows.			** NOTE: This does not completely take care of the RESOLVE			** in the above comment, since it will only notice			** one-row result sets for the current join order.			*/			if (oneRowResultSetForSomeConglom)			{				if (outerCost.rowCount() < rowCount)				{					rowCount = outerCost.rowCount();				}			}			/*			** The estimated cost may be too high for indexes, if the			** estimated row count exceeds the maximum. Only do this			** if we're not doing a full scan, and the start/stop position			** is not constant (i.e. we're doing a join on the first column			** of the index) - the reason being that this is when the			** cost may be inaccurate.			*/			if (cd.isIndex() && startStopFound && ( ! constantStartStop ) )			{				/*				** Does any table outer to this one have a unique key on				** a subset of the joining columns? If so, the maximum number				** of rows that this table can return is the number of rows

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -