Search in sources :

Example 1 with Cost

use of org.apache.phoenix.optimize.Cost in project phoenix by apache.

the class QueryCompiler method compileJoinQuery.

/**
 * Call compileJoinQuery() for join queries recursively down to the leaf JoinTable nodes.
 * If it is a leaf node, call compileSingleFlatQuery() or compileSubquery(), otherwise:
 *      1) If option COST_BASED_OPTIMIZER_ENABLED is on and stats are available, return the
 *         join plan with the best cost. Note that the "best" plan is only locally optimal,
 *         and might or might not be globally optimal.
 *      2) Otherwise, return the join plan compiled with the default strategy.
 * @see JoinCompiler.JoinTable#getApplicableJoinStrategies()
 */
protected QueryPlan compileJoinQuery(StatementContext context, List<Object> binds, JoinTable joinTable, boolean asSubquery, boolean projectPKColumns, List<OrderByNode> orderBy) throws SQLException {
    if (joinTable.getJoinSpecs().isEmpty()) {
        Table table = joinTable.getTable();
        SelectStatement subquery = table.getAsSubquery(orderBy);
        if (!table.isSubselect()) {
            context.setCurrentTable(table.getTableRef());
            PTable projectedTable = table.createProjectedTable(!projectPKColumns, context);
            TupleProjector projector = new TupleProjector(projectedTable);
            TupleProjector.serializeProjectorIntoScan(context.getScan(), projector);
            context.setResolver(FromCompiler.getResolverForProjectedTable(projectedTable, context.getConnection(), subquery.getUdfParseNodes()));
            table.projectColumns(context.getScan());
            return compileSingleFlatQuery(context, subquery, binds, asSubquery, !asSubquery, null, projectPKColumns ? projector : null, true);
        }
        QueryPlan plan = compileSubquery(subquery, false);
        PTable projectedTable = table.createProjectedTable(plan.getProjector());
        context.setResolver(FromCompiler.getResolverForProjectedTable(projectedTable, context.getConnection(), subquery.getUdfParseNodes()));
        return new TupleProjectionPlan(plan, new TupleProjector(plan.getProjector()), table.compilePostFilterExpression(context));
    }
    List<JoinCompiler.Strategy> strategies = joinTable.getApplicableJoinStrategies();
    assert strategies.size() > 0;
    if (!costBased || strategies.size() == 1) {
        return compileJoinQuery(strategies.get(0), context, binds, joinTable, asSubquery, projectPKColumns, orderBy);
    }
    QueryPlan bestPlan = null;
    Cost bestCost = null;
    for (JoinCompiler.Strategy strategy : strategies) {
        StatementContext newContext = new StatementContext(context.getStatement(), context.getResolver(), new Scan(), context.getSequenceManager());
        QueryPlan plan = compileJoinQuery(strategy, newContext, binds, joinTable, asSubquery, projectPKColumns, orderBy);
        Cost cost = plan.getCost();
        if (bestPlan == null || cost.compareTo(bestCost) < 0) {
            bestPlan = plan;
            bestCost = cost;
        }
    }
    context.setResolver(bestPlan.getContext().getResolver());
    context.setCurrentTable(bestPlan.getContext().getCurrentTable());
    return bestPlan;
}
Also used : Table(org.apache.phoenix.compile.JoinCompiler.Table) JoinTable(org.apache.phoenix.compile.JoinCompiler.JoinTable) PTable(org.apache.phoenix.schema.PTable) TupleProjector(org.apache.phoenix.execute.TupleProjector) TupleProjectionPlan(org.apache.phoenix.execute.TupleProjectionPlan) Cost(org.apache.phoenix.optimize.Cost) PTable(org.apache.phoenix.schema.PTable) SelectStatement(org.apache.phoenix.parse.SelectStatement) Scan(org.apache.hadoop.hbase.client.Scan)

Example 2 with Cost

use of org.apache.phoenix.optimize.Cost in project phoenix by apache.

the class ClientAggregatePlan method getCost.

@Override
public Cost getCost() {
    Double outputBytes = this.accept(new ByteCountVisitor());
    Double inputRows = this.getDelegate().accept(new RowCountVisitor());
    Double rowWidth = this.accept(new AvgRowWidthVisitor());
    if (inputRows == null || outputBytes == null || rowWidth == null) {
        return Cost.UNKNOWN;
    }
    double inputBytes = inputRows * rowWidth;
    double rowsBeforeHaving = RowCountVisitor.aggregate(RowCountVisitor.filter(inputRows.doubleValue(), RowCountVisitor.stripSkipScanFilter(context.getScan().getFilter())), groupBy);
    double rowsAfterHaving = RowCountVisitor.filter(rowsBeforeHaving, having);
    double bytesBeforeHaving = rowWidth * rowsBeforeHaving;
    double bytesAfterHaving = rowWidth * rowsAfterHaving;
    int parallelLevel = CostUtil.estimateParallelLevel(false, context.getConnection().getQueryServices());
    Cost cost = CostUtil.estimateAggregateCost(inputBytes, bytesBeforeHaving, groupBy, parallelLevel);
    if (!orderBy.getOrderByExpressions().isEmpty()) {
        Cost orderByCost = CostUtil.estimateOrderByCost(bytesAfterHaving, outputBytes, parallelLevel);
        cost = cost.plus(orderByCost);
    }
    return super.getCost().plus(cost);
}
Also used : ByteCountVisitor(org.apache.phoenix.execute.visitor.ByteCountVisitor) RowCountVisitor(org.apache.phoenix.execute.visitor.RowCountVisitor) AvgRowWidthVisitor(org.apache.phoenix.execute.visitor.AvgRowWidthVisitor) Cost(org.apache.phoenix.optimize.Cost)

Example 3 with Cost

use of org.apache.phoenix.optimize.Cost in project phoenix by apache.

the class ClientScanPlan method getCost.

@Override
public Cost getCost() {
    Double inputBytes = this.getDelegate().accept(new ByteCountVisitor());
    Double outputBytes = this.accept(new ByteCountVisitor());
    if (inputBytes == null || outputBytes == null) {
        return Cost.UNKNOWN;
    }
    int parallelLevel = CostUtil.estimateParallelLevel(false, context.getConnection().getQueryServices());
    Cost cost = new Cost(0, 0, 0);
    if (!orderBy.getOrderByExpressions().isEmpty()) {
        Cost orderByCost = CostUtil.estimateOrderByCost(inputBytes, outputBytes, parallelLevel);
        cost = cost.plus(orderByCost);
    }
    return super.getCost().plus(cost);
}
Also used : ByteCountVisitor(org.apache.phoenix.execute.visitor.ByteCountVisitor) Cost(org.apache.phoenix.optimize.Cost)

Example 4 with Cost

use of org.apache.phoenix.optimize.Cost in project phoenix by apache.

the class CorrelatePlan method getCost.

@Override
public Cost getCost() {
    Double lhsByteCount = delegate.accept(new ByteCountVisitor());
    Double rhsRowCount = rhs.accept(new RowCountVisitor());
    if (lhsByteCount == null || rhsRowCount == null) {
        return Cost.UNKNOWN;
    }
    Cost cost = new Cost(0, 0, lhsByteCount * rhsRowCount);
    Cost lhsCost = delegate.getCost();
    return cost.plus(lhsCost).plus(rhs.getCost());
}
Also used : ByteCountVisitor(org.apache.phoenix.execute.visitor.ByteCountVisitor) RowCountVisitor(org.apache.phoenix.execute.visitor.RowCountVisitor) Cost(org.apache.phoenix.optimize.Cost)

Example 5 with Cost

use of org.apache.phoenix.optimize.Cost in project phoenix by apache.

the class HashJoinPlan method getCost.

@Override
public Cost getCost() {
    try {
        Long r = delegate.getEstimatedRowsToScan();
        Double w = delegate.accept(new AvgRowWidthVisitor());
        if (r == null || w == null) {
            return Cost.UNKNOWN;
        }
        int parallelLevel = CostUtil.estimateParallelLevel(true, getContext().getConnection().getQueryServices());
        double rowWidth = w;
        double rows = RowCountVisitor.filter(r.doubleValue(), RowCountVisitor.stripSkipScanFilter(delegate.getContext().getScan().getFilter()));
        double bytes = rowWidth * rows;
        Cost cost = Cost.ZERO;
        double rhsByteSum = 0.0;
        for (int i = 0; i < subPlans.length; i++) {
            double lhsBytes = bytes;
            Double rhsRows = subPlans[i].getInnerPlan().accept(new RowCountVisitor());
            Double rhsWidth = subPlans[i].getInnerPlan().accept(new AvgRowWidthVisitor());
            if (rhsRows == null || rhsWidth == null) {
                return Cost.UNKNOWN;
            }
            double rhsBytes = rhsWidth * rhsRows;
            rows = RowCountVisitor.join(rows, rhsRows, joinInfo.getJoinTypes()[i]);
            rowWidth = AvgRowWidthVisitor.join(rowWidth, rhsWidth, joinInfo.getJoinTypes()[i]);
            bytes = rowWidth * rows;
            cost = cost.plus(CostUtil.estimateHashJoinCost(lhsBytes, rhsBytes, bytes, subPlans[i].hasKeyRangeExpression(), parallelLevel));
            rhsByteSum += rhsBytes;
        }
        if (rhsByteSum > serverCacheLimit) {
            return Cost.UNKNOWN;
        }
        // Calculate the cost of aggregation and ordering that is performed with the HashJoinPlan
        if (delegate instanceof AggregatePlan) {
            AggregatePlan aggPlan = (AggregatePlan) delegate;
            double rowsBeforeHaving = RowCountVisitor.aggregate(rows, aggPlan.getGroupBy());
            double rowsAfterHaving = RowCountVisitor.filter(rowsBeforeHaving, aggPlan.getHaving());
            double bytesBeforeHaving = rowWidth * rowsBeforeHaving;
            double bytesAfterHaving = rowWidth * rowsAfterHaving;
            Cost aggCost = CostUtil.estimateAggregateCost(bytes, bytesBeforeHaving, aggPlan.getGroupBy(), parallelLevel);
            cost = cost.plus(aggCost);
            rows = rowsAfterHaving;
            bytes = bytesAfterHaving;
        }
        double outputRows = RowCountVisitor.limit(rows, delegate.getLimit());
        double outputBytes = rowWidth * outputRows;
        if (!delegate.getOrderBy().getOrderByExpressions().isEmpty()) {
            int parallelLevel2 = CostUtil.estimateParallelLevel(delegate instanceof ScanPlan, getContext().getConnection().getQueryServices());
            Cost orderByCost = CostUtil.estimateOrderByCost(bytes, outputBytes, parallelLevel);
            cost = cost.plus(orderByCost);
        }
        // Calculate the cost of child nodes
        Cost lhsCost = new Cost(0, 0, r.doubleValue() * w);
        Cost rhsCost = Cost.ZERO;
        for (SubPlan subPlan : subPlans) {
            rhsCost = rhsCost.plus(subPlan.getInnerPlan().getCost());
        }
        return cost.plus(lhsCost).plus(rhsCost);
    } catch (SQLException e) {
    }
    return Cost.UNKNOWN;
}
Also used : RowCountVisitor(org.apache.phoenix.execute.visitor.RowCountVisitor) AvgRowWidthVisitor(org.apache.phoenix.execute.visitor.AvgRowWidthVisitor) SQLException(java.sql.SQLException) AtomicLong(java.util.concurrent.atomic.AtomicLong) Cost(org.apache.phoenix.optimize.Cost)

Aggregations

Cost (org.apache.phoenix.optimize.Cost)9 ByteCountVisitor (org.apache.phoenix.execute.visitor.ByteCountVisitor)6 SQLException (java.sql.SQLException)4 AvgRowWidthVisitor (org.apache.phoenix.execute.visitor.AvgRowWidthVisitor)3 RowCountVisitor (org.apache.phoenix.execute.visitor.RowCountVisitor)3 Scan (org.apache.hadoop.hbase.client.Scan)2 ImmutableSet (com.google.common.collect.ImmutableSet)1 ParameterMetaData (java.sql.ParameterMetaData)1 List (java.util.List)1 Set (java.util.Set)1 AtomicLong (java.util.concurrent.atomic.AtomicLong)1 ColumnResolver (org.apache.phoenix.compile.ColumnResolver)1 ExplainPlan (org.apache.phoenix.compile.ExplainPlan)1 GroupBy (org.apache.phoenix.compile.GroupByCompiler.GroupBy)1 JoinTable (org.apache.phoenix.compile.JoinCompiler.JoinTable)1 Table (org.apache.phoenix.compile.JoinCompiler.Table)1 OrderBy (org.apache.phoenix.compile.OrderByCompiler.OrderBy)1 QueryPlan (org.apache.phoenix.compile.QueryPlan)1 RowProjector (org.apache.phoenix.compile.RowProjector)1 SequenceManager (org.apache.phoenix.compile.SequenceManager)1