Package org.apache.derby.iapi.sql.compile

Examples of org.apache.derby.iapi.sql.compile.CostEstimate


    /*
    ** 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);
  }
View Full Code Here


              optimizer,
              rightResultSet,
              (PredicateList) null,
              outerCost);

    CostEstimate costEstimate = getCostEstimate(optimizer);
        CostEstimate leftCostEstimate = leftResultSet.getCostEstimate();
        CostEstimate rightCostEstimate = rightResultSet.getCostEstimate();
        // The cost is the sum of the two child costs plus the cost of sorting the union.
        costEstimate.setCost( leftCostEstimate.getEstimatedCost() + rightCostEstimate.getEstimatedCost(),
                              getRowCountEstimate( leftCostEstimate.rowCount(),
                                                   rightCostEstimate.rowCount()),
                              getSingleScanRowCountEstimate( leftCostEstimate.singleScanRowCount(),
                                                             rightCostEstimate.singleScanRowCount()));

        return costEstimate;
    } // End of estimateCost
View Full Code Here

    throws StandardException
  {
    if (finalCostEstimate != null)
      return finalCostEstimate;

    CostEstimate leftCE = leftResultSet.getFinalCostEstimate();
    CostEstimate rightCE = rightResultSet.getFinalCostEstimate();

    finalCostEstimate = getNewCostEstimate();
    finalCostEstimate.setCost(
      leftCE.getEstimatedCost() + rightCE.getEstimatedCost(),
      getRowCountEstimate(leftCE.rowCount(), rightCE.rowCount()),
      getSingleScanRowCountEstimate(leftCE.singleScanRowCount(),
        rightCE.singleScanRowCount()));

    return finalCostEstimate;
  }
View Full Code Here

    ** strategies like materialization (hash join can work only on
    ** base tables).  The join strategy for a base table under a
    ** ProjectRestrict is set in the base table itself.
    */

    CostEstimate childCost;

    costEstimate = getCostEstimate(optimizer);

    /*
    ** Don't re-optimize a child result set that has already been fully
    ** optimized.  For example, if the child result set is a SelectNode,
    ** it will be changed to a ProjectRestrictNode, which we don't want
    ** to re-optimized.
    */
    // NOTE: TO GET THE RIGHT COST, THE CHILD RESULT MAY HAVE TO BE
    // OPTIMIZED MORE THAN ONCE, BECAUSE THE NUMBER OF OUTER ROWS
    // MAY BE DIFFERENT EACH TIME.
    // if (childResultOptimized)
    //   return costEstimate;

    // It's possible that a call to optimize the left/right will cause
    // a new "truly the best" plan to be stored in the underlying base
    // tables.  If that happens and then we decide to skip that plan
    // (which we might do if the call to "considerCost()" below decides
    // the current path is infeasible or not the best) we need to be
    // able to revert back to the "truly the best" plans that we had
    // saved before we got here.  So with this next call we save the
    // current plans using "this" node as the key.  If needed, we'll
    // then make the call to revert the plans in OptimizerImpl's
    // getNextDecoratedPermutation() method.
    updateBestPlanMap(ADD_PLAN, this);

    /* If the childResult is instanceof Optimizable, then we optimizeIt.
     * Otherwise, we are going into a new query block.  If the new query
     * block has already had its access path modified, then there is
     * nothing to do.  Otherwise, we must begin the optimization process
     * anew on the new query block.
     */
    if (childResult instanceof Optimizable)
    {
      childCost = ((Optimizable) childResult).optimizeIt(
                              optimizer,
                              restrictionList,
                              outerCost,
                              rowOrdering);
      /* Copy child cost to this node's cost */
      costEstimate.setCost(
              childCost.getEstimatedCost(),
              childCost.rowCount(),
              childCost.singleScanRowCount());


      // Note: we don't call "optimizer.considerCost()" here because
      // a) the child will make that call as part of its own
      // "optimizeIt()" work above, and b) the child might have
      // different criteria for "considering" (i.e. rejecting or
      // accepting) a plan's cost than this ProjectRestrictNode does--
      // and we don't want to override the child's decision.  So as
      // with most operations in this class, if the child is an
      // Optimizable, we just let it do its own work and make its
      // own decisions.
    }
    else if ( ! accessPathModified)
    {
      if (SanityManager.DEBUG)
      {
        if (! ((childResult instanceof SelectNode) ||
                 (childResult instanceof RowResultSetNode)))
        {
          SanityManager.THROWASSERT(
            "childResult is expected to be instanceof " +
            "SelectNode or RowResultSetNode - it is a " +
            childResult.getClass().getName());
        }
      }
      childResult = childResult.optimize(optimizer.getDataDictionary(),
                         restrictionList,
                         outerCost.rowCount());

      /* Copy child cost to this node's cost */
      childCost = childResult.costEstimate;

      costEstimate.setCost(
              childCost.getEstimatedCost(),
              childCost.rowCount(),
              childCost.singleScanRowCount());

      /* Note: Prior to the fix for DERBY-781 we had calls here
       * to set the cost estimate for BestAccessPath and
       * BestSortAvoidancePath to equal costEstimate.  That used
       * to be okay because prior to DERBY-781 we would only
View Full Code Here

    /*
    ** An outer join returns at least as many rows as in the outer
    ** table. Even if this started as a right outer join, it will
    ** have been transformed to a left outer join by this point.
    */
    CostEstimate outerCost = getLeftResultSet().getCostEstimate();

    if (costEstimate.rowCount() < outerCost.rowCount())
    {
      costEstimate.setCost(costEstimate.getEstimatedCost(),
                 outerCost.rowCount(),
                 outerCost.rowCount());
    }
  }
View Full Code Here

          prevSingleScanRowCount = outermostCostEstimate.singleScanRowCount();
        }
        else
        {
          prevPosition = proposedJoinOrder[joinPosition - 1];
          CostEstimate localCE =
            optimizableList.
              getOptimizable(prevPosition).
                getBestAccessPath().
                  getCostEstimate();
          prevRowCount = localCE.rowCount();
          prevSingleScanRowCount = localCE.singleScanRowCount();
        }

        /*
        ** If there is no feasible join order, the cost estimate
        ** in the best access path may never have been set.
        ** In this case, do not subtract anything from the
        ** current cost, since nothing was added to the current
        ** cost.
        */
        double newCost = currentCost.getEstimatedCost();
        double pullCost = 0.0;
        CostEstimate pullCostEstimate =
                pullMe.getBestAccessPath().getCostEstimate();
        if (pullCostEstimate != null)
        {
          pullCost = pullCostEstimate.getEstimatedCost();

          newCost -= pullCost;

          /*
          ** It's possible for newCost to go negative here due to
          ** loss of precision.
          */
          if (newCost < 0.0)
            newCost = 0.0;
        }

        /* If we are choosing a new outer table, then
         * we rest the starting cost to the outermostCost.
         * (Thus avoiding any problems with floating point
         * accuracy and going negative.)
         */
        if (joinPosition == 0)
        {
          if (outermostCostEstimate != null)
          {
            newCost = outermostCostEstimate.getEstimatedCost();
          }
          else
          {
            newCost = 0.0;
          }
        }

        currentCost.setCost(
          newCost,
          prevRowCount,
          prevSingleScanRowCount);
       
        /*
        ** Subtract from the sort avoidance cost if there is a
        ** required row ordering.
        **
        ** NOTE: It is not necessary here to check whether the
        ** best cost was ever set for the sort avoidance path,
        ** because it considerSortAvoidancePath() would not be
        ** set if there cost were not set.
        */
        if (requiredRowOrdering != null)
        {
          if (pullMe.considerSortAvoidancePath())
          {
            AccessPath ap = pullMe.getBestSortAvoidancePath();
            double     prevEstimatedCost = 0.0d;

            /*
            ** Subtract the sort avoidance cost estimate of the
            ** optimizable being removed from the total sort
            ** avoidance cost estimate.
            **
            ** The total cost is the sum of all the costs, but the
            ** total number of rows is the number of rows returned
            ** by the innermost optimizable.
            */
            if (joinPosition == 0)
            {
              prevRowCount = outermostCostEstimate.rowCount();
              prevSingleScanRowCount = outermostCostEstimate.singleScanRowCount();
              /* If we are choosing a new outer table, then
               * we rest the starting cost to the outermostCost.
               * (Thus avoiding any problems with floating point
               * accuracy and going negative.)
               */
              prevEstimatedCost = outermostCostEstimate.getEstimatedCost();
            }
            else
            {
              CostEstimate localCE =
                optimizableList.
                  getOptimizable(prevPosition).
                    getBestSortAvoidancePath().
                      getCostEstimate();
              prevRowCount = localCE.rowCount();
              prevSingleScanRowCount = localCE.singleScanRowCount();
              prevEstimatedCost = currentSortAvoidanceCost.getEstimatedCost() -
                          ap.getCostEstimate().getEstimatedCost();
            }

            currentSortAvoidanceCost.setCost(
              prevEstimatedCost,
              prevRowCount,
              prevSingleScanRowCount);

            /*
            ** Remove the table from the best row ordering.
            ** It should not be necessary to remove it from
            ** the current row ordering, because it is
            ** maintained as we step through the access paths
            ** for the current Optimizable.
            */
            bestRowOrdering.removeOptimizable(
                          pullMe.getTableNumber());

            /*
            ** When removing a table from the join order,
            ** the best row ordering for the remaining outer tables
            ** becomes the starting point for the row ordering of
            ** the current table.
            */
            bestRowOrdering.copy(currentRowOrdering);
          }
        }

        /*
        ** Pull the predicates at from the optimizable and put
        ** them back in the predicate list.
        **
        ** NOTE: This is a little inefficient because it pulls the
        ** single-table predicates, which are guaranteed to always
        ** be pushed to the same optimizable.  We could make this
        ** leave the single-table predicates where they are.
        */
        pullMe.pullOptPredicates(predicateList);

        /*
        ** When we pull an Optimizable we need to go through and
        ** load whatever best path we found for that Optimizable
        ** with respect to _this_ OptimizerImpl.  An Optimizable
        ** can have different "best paths" for different Optimizer
        ** Impls if there are subqueries beneath it; we need to make
        ** sure that when we pull it, it's holding the best path as
        ** as we determined it to be for _us_.
        **
        ** NOTE: We we only reload the best plan if it's necessary
        ** to do so--i.e. if the best plans aren't already loaded.
        ** The plans will already be loaded if the last complete
        ** join order we had was the best one so far, because that
        ** means we called "rememberAsBest" on every Optimizable
        ** in the list and, as part of that call, we will run through
        ** and set trulyTheBestAccessPath for the entire subtree.
        ** So if we haven't tried any other plans since then,
        ** we know that every Optimizable (and its subtree) already
        ** has the correct best plan loaded in its trulyTheBest
        ** path field.  It's good to skip the load in this case
        ** because 'reloading best plans' involves walking the
        ** entire subtree of _every_ Optimizable in the list, which
        ** can be expensive if there are deeply nested subqueries.
        */
        if (reloadBestPlan)
          pullMe.updateBestPlanMap(FromTable.LOAD_PLAN, this);

        /* Mark current join position as unused */
        proposedJoinOrder[joinPosition] = -1;
      }

      /* Have we exhausted all the optimizables at this join position? */
      if (nextOptimizable >= numOptimizables)
      {
        /*
        ** If we're not optimizing the join order, remember the first
        ** join order.
        */
        if ( ! optimizableList.optimizeJoinOrder())
        {
          // Verify that the user specified a legal join order
          if ( ! optimizableList.legalJoinOrder(numTablesInQuery))
          {
            if (optimizerTrace)
            {
              trace(ILLEGAL_USER_JOIN_ORDER, 0, 0, 0.0, null);
            }

            throw StandardException.newException(SQLState.LANG_ILLEGAL_FORCED_JOIN_ORDER);
          }

          if (optimizerTrace)
          {
            trace(USER_JOIN_ORDER_OPTIMIZED, 0, 0, 0.0, null);
          }

          desiredJoinOrderFound = true;
        }

        if (permuteState == READY_TO_JUMP && joinPosition > 0 && joinPosition == numOptimizables-1)
        {
          permuteState = JUMPING;

          /* A simple heuristics is that the row count we got indicates a potentially
           * good join order.  We'd like row count to get big as late as possible, so
           * that less load is carried over.
           */
          double rc[] = new double[numOptimizables];
          for (int i = 0; i < numOptimizables; i++)
          {
            firstLookOrder[i] = i;
            CostEstimate ce = optimizableList.getOptimizable(i).
                        getBestAccessPath().getCostEstimate();
            if (ce == null)
            {
              permuteState = READY_TO_JUMP;  //come again?
              break;
            }
            rc[i] = ce.singleScanRowCount();
          }
          if (permuteState == JUMPING)
          {
            boolean doIt = false;
            int temp;
View Full Code Here

    ** When all the access paths have been looked at, we know what the
    ** cheapest one is, so remember it.  Only do this if a cost estimate
    ** has been set for the best access path - one will not have been
    ** set if no feasible plan has been found.
    */
    CostEstimate ce = curOpt.getBestAccessPath().getCostEstimate();
    if ( ( ! retval ) && (ce != null))
    {
      /*
      ** Add the cost of the current optimizable to the total cost.
      ** The total cost is the sum of all the costs, but the total
      ** number of rows is the number of rows returned by the innermost
      ** optimizable.
      */
      currentCost.setCost(
        currentCost.getEstimatedCost() + ce.getEstimatedCost(),
        ce.rowCount(),
        ce.singleScanRowCount());

      if (curOpt.considerSortAvoidancePath() &&
        requiredRowOrdering != null)
      {
        /* Add the cost for the sort avoidance path, if there is one */
        ce = curOpt.getBestSortAvoidancePath().getCostEstimate();

        currentSortAvoidanceCost.setCost(
          currentSortAvoidanceCost.getEstimatedCost() +
            ce.getEstimatedCost(),
          ce.rowCount(),
          ce.singleScanRowCount());
      }

      if (optimizerTrace)
      {
        trace(TOTAL_COST_NON_SA_PLAN, 0, 0, 0.0, null);
View Full Code Here

  {
    /*
    ** Get the cost of the outer plan so far.  This gives us the current
    ** estimated rows, ordering, etc.
    */
    CostEstimate outerCost;
    if (joinPosition == 0)
    {
      outerCost = outermostCostEstimate;
    }
    else
View Full Code Here

                      ConglomerateDescriptor cd,
                      OptimizablePredicateList predList,
                      CostEstimate outerCost)
        throws StandardException
  {
    CostEstimate estimatedCost = estimateTotalCost(predList,
                            cd,
                            outerCost,
                            optimizable);

    // Before considering the cost, make sure we set the optimizable's
    // "current" cost to be the one that we found.  Doing this allows
    // us to compare "current" with "best" later on to find out if
    // the "current" plan is also the "best" one this round--if it's
    // not then we'll have to revert back to whatever the best plan is.
    // That check is performed in getNextDecoratedPermutation() of
    // this class.
    optimizable.getCurrentAccessPath().setCostEstimate(estimatedCost);

    /*
    ** Skip this access path if it takes too much memory.
    **
    ** NOTE: The default assumption here is that the number of rows in
    ** a single scan is the total number of rows divided by the number
    ** of outer rows.  The optimizable may over-ride this assumption.
    */
    // RESOLVE: The following call to memoryUsageOK does not behave
    // correctly if outerCost.rowCount() is POSITIVE_INFINITY; see
    // DERBY-1259.
    if( ! optimizable.memoryUsageOK( estimatedCost.rowCount() / outerCost.rowCount(), maxMemoryPerTable))
    {
      if (optimizerTrace)
      {
        trace(SKIPPING_DUE_TO_EXCESS_MEMORY, 0, 0, 0.0, null);
      }
      return;
    }

    /* Pick the cheapest cost for this particular optimizable. */
    AccessPath ap = optimizable.getBestAccessPath();
    CostEstimate bestCostEstimate = ap.getCostEstimate();

    if ((bestCostEstimate == null) ||
      bestCostEstimate.isUninitialized() ||
      (estimatedCost.compare(bestCostEstimate) < 0))
    {
      ap.setConglomerateDescriptor(cd);
      ap.setCostEstimate(estimatedCost);
      ap.setCoveringIndexScan(optimizable.isCoveringIndex(cd));

      /*
      ** It's a non-matching index scan either if there is no
      ** predicate list, or nothing in the predicate list is useful
      ** for limiting the scan.
      */
      ap.setNonMatchingIndexScan(
                  (predList == null) ||
                  ( ! ( predList.useful(optimizable, cd) ) )
                  );
      ap.setLockMode(optimizable.getCurrentAccessPath().getLockMode());
      optimizable.rememberJoinStrategyAsBest(ap);
    }

    /*
    ** Keep track of the best sort-avoidance path if there is a
    ** required row ordering.
    */
    if (requiredRowOrdering != null)
    {
      /*
      ** The current optimizable can avoid a sort only if the
      ** outer one does, also (if there is an outer one).
      */
      if (joinPosition == 0 ||
        optimizableList.getOptimizable(
                    proposedJoinOrder[joinPosition - 1]).
                        considerSortAvoidancePath())
      {
        /*
        ** There is a required row ordering - does the proposed access
        ** path avoid a sort?
        */
        if (requiredRowOrdering.sortRequired(currentRowOrdering,
                            assignedTableMap)
                    == RequiredRowOrdering.NOTHING_REQUIRED)
        {
          ap = optimizable.getBestSortAvoidancePath();
          bestCostEstimate = ap.getCostEstimate();

          /* Is this the cheapest sort-avoidance path? */
          if ((bestCostEstimate == null) ||
            bestCostEstimate.isUninitialized() ||
            (estimatedCost.compare(bestCostEstimate) < 0))
          {
            ap.setConglomerateDescriptor(cd);
            ap.setCostEstimate(estimatedCost);
            ap.setCoveringIndexScan(
View Full Code Here

     * associated with it in that case.  So, we now choose the new
     * access path if it is the same cost or cheaper than the current
     * access path.
     */
    AccessPath ap = optimizable.getBestAccessPath();
    CostEstimate bestCostEstimate = ap.getCostEstimate();

    if ((bestCostEstimate == null) ||
      bestCostEstimate.isUninitialized() ||
      (estimatedCost.compare(bestCostEstimate) <= 0))
    {
      ap.setCostEstimate(estimatedCost);
      optimizable.rememberJoinStrategyAsBest(ap);
    }

    /*
    ** Keep track of the best sort-avoidance path if there is a
    ** required row ordering.
    */
    if (requiredRowOrdering != null)
    {
      /*
      ** The current optimizable can avoid a sort only if the
      ** outer one does, also (if there is an outer one).
      */
      if (joinPosition == 0 ||
        optimizableList.getOptimizable(
                    proposedJoinOrder[joinPosition - 1]).
                        considerSortAvoidancePath())
      {
        /*
        ** There is a required row ordering - does the proposed access
        ** path avoid a sort?
        */
        if (requiredRowOrdering.sortRequired(currentRowOrdering,
                            assignedTableMap)
                    == RequiredRowOrdering.NOTHING_REQUIRED)
        {
          ap = optimizable.getBestSortAvoidancePath();
          bestCostEstimate = ap.getCostEstimate();

          /* Is this the cheapest sort-avoidance path? */
          if ((bestCostEstimate == null) ||
            bestCostEstimate.isUninitialized() ||
            (estimatedCost.compare(bestCostEstimate) < 0))
          {
            ap.setCostEstimate(estimatedCost);
            optimizable.rememberJoinStrategyAsBest(ap);
            optimizable.rememberSortAvoidancePath();
View Full Code Here

TOP

Related Classes of org.apache.derby.iapi.sql.compile.CostEstimate

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.