use of org.apache.jackrabbit.oak.query.plan.ExecutionPlan in project jackrabbit-oak by apache.
the class QueryImpl method prepare.
@Override
public void prepare() {
if (prepared) {
return;
}
prepared = true;
List<SourceImpl> sources = source.getInnerJoinSelectors();
List<JoinConditionImpl> conditions = source.getInnerJoinConditions();
if (sources.size() <= 1) {
// simple case (no join)
estimatedCost = source.prepare().getEstimatedCost();
isSortedByIndex = canSortByIndex();
return;
}
// use a greedy algorithm
SourceImpl result = null;
Set<SourceImpl> available = new HashSet<SourceImpl>();
// the query is only slow if all possible join orders are slow
// (in theory, due to using the greedy algorithm, a query might be considered
// slow even thought there is a plan that doesn't need to use traversal, but
// only for 3-way and higher joins, and only if traversal is considered very fast)
boolean isPotentiallySlowJoin = true;
while (sources.size() > 0) {
int bestIndex = 0;
double bestCost = Double.POSITIVE_INFINITY;
ExecutionPlan bestPlan = null;
SourceImpl best = null;
for (int i = 0; i < sources.size(); i++) {
SourceImpl test = buildJoin(result, sources.get(i), conditions);
if (test == null) {
// no join condition
continue;
}
ExecutionPlan testPlan = test.prepare();
double cost = testPlan.getEstimatedCost();
if (best == null || cost < bestCost) {
bestPlan = testPlan;
bestCost = cost;
bestIndex = i;
best = test;
}
if (!potentiallySlowTraversalQuery) {
isPotentiallySlowJoin = false;
}
test.unprepare();
}
available.add(sources.remove(bestIndex));
result = best;
best.prepare(bestPlan);
}
potentiallySlowTraversalQuery = isPotentiallySlowJoin;
estimatedCost = result.prepare().getEstimatedCost();
source = result;
isSortedByIndex = canSortByIndex();
}
use of org.apache.jackrabbit.oak.query.plan.ExecutionPlan in project jackrabbit-oak by apache.
the class JoinImpl method prepare.
@Override
public ExecutionPlan prepare() {
if (plan != null) {
return plan;
}
applyJoinConditions();
// the estimated cost is the cost of the left selector,
// plus twice the cost of the right selector (we expect
// two rows for the right selector for each node
// on the left selector)
ExecutionPlan leftPlan = left.prepare();
ExecutionPlan rightPlan = right.prepare();
double cost = leftPlan.getEstimatedCost() + 2 * rightPlan.getEstimatedCost();
plan = new JoinExecutionPlan(this, leftPlan, rightPlan, cost);
return plan;
}
Aggregations