Search in sources :

Example 16 with CostEstimate

use of org.apache.derby.iapi.sql.compile.CostEstimate in project derby by apache.

the class SetOperatorNode method modifyAccessPath.

/**
 * @see Optimizable#modifyAccessPath
 *
 * @exception StandardException		Thrown on error
 */
public Optimizable modifyAccessPath(JBitSet outerTables, PredicateList predList) throws StandardException {
    // is the equijoin predicate that is required by hash join.
    if ((predList != null) && !getTrulyTheBestAccessPath().getJoinStrategy().isHashJoin()) {
        for (int i = predList.size() - 1; i >= 0; i--) if (pushOptPredicate(predList.getOptPredicate(i)))
            predList.removeOptPredicate(i);
    }
    /*
		 * It's possible that we tried to push a predicate down to this node's
		 * children but failed to do so.  This can happen if this node's
		 * children both match the criteria for pushing a predicate (namely,
		 * they reference base tables) but the children's children do not.
		 * Ex.
		 *  select * from
		 *    (select i,j from t2 UNION
		 *      values (1,1),(2,2),(3,3),(4,4) UNION
		 *      select i,j from t1
		 *    ) x0 (i,j),
		 *    t5 where x0.i = t5.i;
		 *
		 * This will yield a tree resembling the following:
		 *
		 *                     UNION
		 *                    /     \
		 *               UNION     SELECT (T1)
		 *              /     \
		 *        SELECT (T2)  VALUES
		 *
		 * In this case the top UNION ("this") will push the predicate down,
		 * but the second UNION will _not_ push the predicate because
		 * it can't be pushed to the VALUES clause.  This means that
		 * after we're done modifying the paths for "this" node (the top
		 * UNION), the predicate will still be sitting in our leftOptPredicates
		 * list.  If that's the case, then we have to make sure the predicate,
		 * which was _not_ enforced in the left child, is enforced at this
		 * level.  We do that by generating a ProjectRestrictNode above this
		 * node.  Yes, this means the predicate will actually be applied
		 * twice to the right child (in this case), but that's okay as it
		 * won't affect the results.
		 */
    // Get the cost estimate for this node so that we can put it in
    // the new ProjectRestrictNode, if one is needed.
    CostEstimate ce = getFinalCostEstimate();
    // Modify this node's access paths.
    ResultSetNode topNode = (ResultSetNode) modifyAccessPath(outerTables);
    /* Now see if there are any left over predicates; if so, then we
		 * have to generate a ProjectRestrictNode.  Note: we want to check
		 * all SetOpNodes that exist in the subtree rooted at this SetOpNode.
		 * Since we just modified access paths on this node, it's possible
		 * that the SetOperatorNode chain (if there was one) is now "broken"
		 * as a result of the insertion of new nodes.  For example, prior
		 * to modification of access paths we may have a chain such as:
		 *
		 *                          UnionNode (0)
		 *                          /       \
		 *                 UnionNode (1)    SelectNode (2)
		 *                 /        \ 
		 *      SelectNode (3)     SelectNode (4)
		 *
		 * Now if UnionNode(1) did not specify "ALL" then as part of the
		 * above call to modifyAccessPaths() we will have inserted a
		 * DistinctNode above it, thus giving:
		 *
		 *                          UnionNode (0)
		 *                          /       \
		 *                 DistinctNode (5)  SelectNode (2)
		 *                      |
		 *                 UnionNode (1)
		 *                 /        \ 
		 *      SelectNode (3)     SelectNode (4)
		 *
		 * So our chain of UnionNode's has now been "broken" by an intervening
		 * DistinctNode.  For this reason we can't just walk the chain of
		 * SetOperatorNodes looking for unpushed predicates (because the
		 * chain might be broken and then we could miss some nodes). Instead,
		 * we have to get a collection of all relevant nodes that exist beneath
		 * this SetOpNode and call hasUnPushedPredicates() on each one.  For
		 * now we only consider UnionNodes to be "relevant" because those are
		 * the only ones that might actually have unpushed predicates.
		 * 
		 * If we find any UnionNodes that *do* have unpushed predicates then
		 * we have to use a PRN to enforce the predicate at the level of
		 * this, the top-most, SetOperatorNode.
		 */
    // Find all UnionNodes in the subtree.
    CollectNodesVisitor<UnionNode> cnv = new CollectNodesVisitor<UnionNode>(UnionNode.class);
    this.accept(cnv);
    // Now see if any of them have unpushed predicates.
    boolean genPRN = false;
    for (UnionNode node : cnv.getList()) {
        if (node.hasUnPushedPredicates()) {
            genPRN = true;
            break;
        }
    }
    if (genPRN) {
        // When we generate the project restrict node, we pass in the
        // "pushedPredicates" list because that has the predicates in
        // _unscoped_ form, which means they are intended for _this_
        // node instead of this node's children.  That's exactly what
        // we want.
        ResultSetNode prnRSN = new ProjectRestrictNode(// Child ResultSet
        topNode, // Projection
        topNode.getResultColumns(), // Restriction
        null, // Restriction as PredicateList
        pushedPredicates, // Subquerys in Projection
        null, // Subquerys in Restriction
        null, // Table properties
        null, getContextManager());
        prnRSN.setCostEstimate(ce.cloneMe());
        prnRSN.setReferencedTableMap(topNode.getReferencedTableMap());
        topNode = prnRSN;
    }
    return (Optimizable) topNode;
}
Also used : CostEstimate(org.apache.derby.iapi.sql.compile.CostEstimate) Optimizable(org.apache.derby.iapi.sql.compile.Optimizable)

Example 17 with CostEstimate

use of org.apache.derby.iapi.sql.compile.CostEstimate in project derby by apache.

the class DistinctNode method estimateCost.

/**
 * @see Optimizable#estimateCost
 *
 * @exception StandardException		Thrown on error
 */
@Override
public CostEstimate estimateCost(OptimizablePredicateList predList, ConglomerateDescriptor cd, CostEstimate outerCost, Optimizer optimizer, RowOrdering rowOrdering) throws StandardException {
    // RESOLVE: WE NEED TO ADD IN THE COST OF SORTING HERE, AND FIGURE
    // OUT HOW MANY ROWS WILL BE ELIMINATED.
    CostEstimate childCost = ((Optimizable) childResult).estimateCost(predList, cd, outerCost, optimizer, rowOrdering);
    setCostEstimate(getCostEstimate(optimizer));
    getCostEstimate().setCost(childCost.getEstimatedCost(), childCost.rowCount(), childCost.singleScanRowCount());
    /*
		** No need to use estimateCost on join strategy - that has already
		** been done on the child.
		*/
    return getCostEstimate();
}
Also used : CostEstimate(org.apache.derby.iapi.sql.compile.CostEstimate) Optimizable(org.apache.derby.iapi.sql.compile.Optimizable)

Example 18 with CostEstimate

use of org.apache.derby.iapi.sql.compile.CostEstimate in project derby by apache.

the class FromBaseTable method generateMaxSpecialResultSet.

private void generateMaxSpecialResultSet(ExpressionClassBuilder acb, MethodBuilder mb) throws StandardException {
    ConglomerateDescriptor cd = getTrulyTheBestAccessPath().getConglomerateDescriptor();
    CostEstimate costEst = getFinalCostEstimate();
    int colRefItem = (referencedCols == null) ? -1 : acb.addItem(referencedCols);
    boolean tableLockGranularity = tableDescriptor.getLockGranularity() == TableDescriptor.TABLE_LOCK_GRANULARITY;
    /*
		** getLastIndexKeyResultSet
		** (
		**		activation,			
		**		resultSetNumber,			
		**		resultRowAllocator,			
		**		conglomereNumber,			
		**		tableName,
		**		optimizeroverride			
		**		indexName,			
		**		colRefItem,			
		**		lockMode,			
		**		tableLocked,
		**		isolationLevel,
		**		optimizerEstimatedRowCount,
		**		optimizerEstimatedRowCost,
		**	);
		*/
    acb.pushGetResultSetFactoryExpression(mb);
    acb.pushThisAsActivation(mb);
    mb.push(getResultSetNumber());
    mb.push(acb.addItem(getResultColumns().buildRowTemplate(referencedCols, false)));
    mb.push(cd.getConglomerateNumber());
    mb.push(tableDescriptor.getName());
    // run time statistics.
    if (tableProperties != null)
        mb.push(org.apache.derby.iapi.util.PropertyUtil.sortProperties(tableProperties));
    else
        mb.pushNull("java.lang.String");
    pushIndexName(cd, mb);
    mb.push(colRefItem);
    mb.push(getTrulyTheBestAccessPath().getLockMode());
    mb.push(tableLockGranularity);
    mb.push(getCompilerContext().getScanIsolationLevel());
    mb.push(costEst.singleScanRowCount());
    mb.push(costEst.getEstimatedCost());
    mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, "getLastIndexKeyResultSet", ClassName.NoPutResultSet, 13);
}
Also used : CostEstimate(org.apache.derby.iapi.sql.compile.CostEstimate) ConglomerateDescriptor(org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor)

Example 19 with CostEstimate

use of org.apache.derby.iapi.sql.compile.CostEstimate in project derby by apache.

the class FromTable method startOptimizing.

/**
 * @see Optimizable#startOptimizing
 */
public void startOptimizing(Optimizer optimizer, RowOrdering rowOrdering) {
    resetJoinStrategies(optimizer);
    considerSortAvoidancePath = false;
    /*
		** If there are costs associated with the best and sort access
		** paths, set them to their maximum values, so that any legitimate
		** access path will look cheaper.
		*/
    CostEstimate ce = getBestAccessPath().getCostEstimate();
    if (ce != null)
        ce.setCost(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE);
    ce = getBestSortAvoidancePath().getCostEstimate();
    if (ce != null)
        ce.setCost(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE);
    if (!canBeOrdered())
        rowOrdering.addUnorderedOptimizable(this);
}
Also used : CostEstimate(org.apache.derby.iapi.sql.compile.CostEstimate)

Example 20 with CostEstimate

use of org.apache.derby.iapi.sql.compile.CostEstimate in project derby by apache.

the class JoinNode method getFinalCostEstimate.

/**
 * @see ResultSetNode#getFinalCostEstimate
 *
 * Get the final CostEstimate for this JoinNode.
 *
 * @return	The final CostEstimate for this JoinNode, which is sum
 *  the costs for the inner and outer table.  The number of rows,
 *  though, is that for the inner table only.
 */
@Override
CostEstimate getFinalCostEstimate() throws StandardException {
    // If we already found it, just return it.
    if (getCandidateFinalCostEstimate() != null) {
        return getCandidateFinalCostEstimate();
    }
    CostEstimate leftCE = leftResultSet.getFinalCostEstimate();
    CostEstimate rightCE = rightResultSet.getFinalCostEstimate();
    setCandidateFinalCostEstimate(getNewCostEstimate());
    getCandidateFinalCostEstimate().setCost(leftCE.getEstimatedCost() + rightCE.getEstimatedCost(), rightCE.rowCount(), rightCE.rowCount());
    return getCandidateFinalCostEstimate();
}
Also used : CostEstimate(org.apache.derby.iapi.sql.compile.CostEstimate)

Aggregations

CostEstimate (org.apache.derby.iapi.sql.compile.CostEstimate)25 Optimizable (org.apache.derby.iapi.sql.compile.Optimizable)9 AccessPath (org.apache.derby.iapi.sql.compile.AccessPath)5 OptimizablePredicateList (org.apache.derby.iapi.sql.compile.OptimizablePredicateList)3 CompilerContext (org.apache.derby.iapi.sql.compile.CompilerContext)2 ConglomerateDescriptor (org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor)2 LocalField (org.apache.derby.iapi.services.compiler.LocalField)1 MethodBuilder (org.apache.derby.iapi.services.compiler.MethodBuilder)1 FormatableArrayHolder (org.apache.derby.iapi.services.io.FormatableArrayHolder)1 FormatableBitSet (org.apache.derby.iapi.services.io.FormatableBitSet)1 FormatableIntHolder (org.apache.derby.iapi.services.io.FormatableIntHolder)1 JoinStrategy (org.apache.derby.iapi.sql.compile.JoinStrategy)1 OptimizablePredicate (org.apache.derby.iapi.sql.compile.OptimizablePredicate)1 OptimizerPlan (org.apache.derby.iapi.sql.compile.OptimizerPlan)1 IndexRowGenerator (org.apache.derby.iapi.sql.dictionary.IndexRowGenerator)1 StaticCompiledOpenConglomInfo (org.apache.derby.iapi.store.access.StaticCompiledOpenConglomInfo)1 StoreCostController (org.apache.derby.iapi.store.access.StoreCostController)1 DataValueDescriptor (org.apache.derby.iapi.types.DataValueDescriptor)1 JBitSet (org.apache.derby.iapi.util.JBitSet)1