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;
}
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);
}
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);
}
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());
}
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;
}
Aggregations