Search in sources :

Example 1 with BaseQueryPlan

use of org.apache.phoenix.execute.BaseQueryPlan in project phoenix by apache.

the class QueryOptimizer method getApplicablePlans.

private List<QueryPlan> getApplicablePlans(BaseQueryPlan dataPlan, PhoenixStatement statement, List<? extends PDatum> targetColumns, ParallelIteratorFactory parallelIteratorFactory, boolean stopAtBestPlan) throws SQLException {
    SelectStatement select = (SelectStatement) dataPlan.getStatement();
    // Exit early if we have a point lookup as we can't get better than that
    if (dataPlan.getContext().getScanRanges().isPointLookup() && stopAtBestPlan) {
        return Collections.<QueryPlan>singletonList(dataPlan);
    }
    List<PTable> indexes = Lists.newArrayList(dataPlan.getTableRef().getTable().getIndexes());
    if (indexes.isEmpty() || dataPlan.isDegenerate() || dataPlan.getTableRef().hasDynamicCols() || select.getHint().hasHint(Hint.NO_INDEX)) {
        return Collections.<QueryPlan>singletonList(dataPlan);
    }
    // when the data table is used.
    if (targetColumns.isEmpty()) {
        List<? extends ColumnProjector> projectors = dataPlan.getProjector().getColumnProjectors();
        List<PDatum> targetDatums = Lists.newArrayListWithExpectedSize(projectors.size());
        for (ColumnProjector projector : projectors) {
            targetDatums.add(projector.getExpression());
        }
        targetColumns = targetDatums;
    }
    SelectStatement translatedIndexSelect = IndexStatementRewriter.translate(select, FromCompiler.getResolver(dataPlan.getTableRef()));
    List<QueryPlan> plans = Lists.newArrayListWithExpectedSize(1 + indexes.size());
    plans.add(dataPlan);
    QueryPlan hintedPlan = getHintedQueryPlan(statement, translatedIndexSelect, indexes, targetColumns, parallelIteratorFactory, plans);
    if (hintedPlan != null) {
        if (stopAtBestPlan) {
            return Collections.singletonList(hintedPlan);
        }
        plans.add(0, hintedPlan);
    }
    for (PTable index : indexes) {
        QueryPlan plan = addPlan(statement, translatedIndexSelect, index, targetColumns, parallelIteratorFactory, dataPlan, false);
        if (plan != null) {
            // Query can't possibly return anything so just return this plan.
            if (plan.isDegenerate()) {
                return Collections.singletonList(plan);
            }
            plans.add(plan);
        }
    }
    return hintedPlan == null ? orderPlansBestToWorst(select, plans, stopAtBestPlan) : plans;
}
Also used : PDatum(org.apache.phoenix.schema.PDatum) SelectStatement(org.apache.phoenix.parse.SelectStatement) BaseQueryPlan(org.apache.phoenix.execute.BaseQueryPlan) QueryPlan(org.apache.phoenix.compile.QueryPlan) PTable(org.apache.phoenix.schema.PTable) ColumnProjector(org.apache.phoenix.compile.ColumnProjector)

Example 2 with BaseQueryPlan

use of org.apache.phoenix.execute.BaseQueryPlan in project phoenix by apache.

the class QueryOptimizer method getApplicablePlans.

private List<QueryPlan> getApplicablePlans(QueryPlan dataPlan, PhoenixStatement statement, List<? extends PDatum> targetColumns, ParallelIteratorFactory parallelIteratorFactory, boolean stopAtBestPlan) throws SQLException {
    if (!useIndexes) {
        return Collections.singletonList(dataPlan);
    }
    if (dataPlan instanceof BaseQueryPlan) {
        return getApplicablePlans((BaseQueryPlan) dataPlan, statement, targetColumns, parallelIteratorFactory, stopAtBestPlan);
    }
    SelectStatement select = (SelectStatement) dataPlan.getStatement();
    ColumnResolver resolver = FromCompiler.getResolverForQuery(select, statement.getConnection());
    Map<TableRef, QueryPlan> dataPlans = null;
    // non-correlated sub-query, then rewrite the query with found index tables.
    if (select.isJoin() || (select.getWhere() != null && select.getWhere().hasSubquery())) {
        JoinCompiler.JoinTable join = JoinCompiler.compile(statement, select, resolver);
        Map<TableRef, TableRef> replacement = null;
        for (JoinCompiler.Table table : join.getTables()) {
            if (table.isSubselect())
                continue;
            TableRef tableRef = table.getTableRef();
            SelectStatement stmt = table.getAsSubqueryForOptimization(tableRef.equals(dataPlan.getTableRef()));
            // so the filter conditions can be taken into account in optimization.
            if (stmt.getWhere() != null && stmt.getWhere().hasSubquery()) {
                StatementContext context = new StatementContext(statement, resolver, new Scan(), new SequenceManager(statement));
                ;
                ParseNode dummyWhere = GenSubqueryParamValuesRewriter.replaceWithDummyValues(stmt.getWhere(), context);
                stmt = FACTORY.select(stmt, dummyWhere);
            }
            // TODO: It seems inefficient to be recompiling the statement again inside of this optimize call
            QueryPlan subDataPlan = new QueryCompiler(statement, stmt, FromCompiler.getResolverForQuery(stmt, statement.getConnection()), false, false, null).compile();
            QueryPlan subPlan = optimize(statement, subDataPlan);
            TableRef newTableRef = subPlan.getTableRef();
            if (!newTableRef.equals(tableRef)) {
                if (replacement == null) {
                    replacement = new HashMap<TableRef, TableRef>();
                    dataPlans = new HashMap<TableRef, QueryPlan>();
                }
                replacement.put(tableRef, newTableRef);
                dataPlans.put(newTableRef, subDataPlan);
            }
        }
        if (replacement != null) {
            select = rewriteQueryWithIndexReplacement(statement.getConnection(), resolver, select, replacement);
            resolver = FromCompiler.getResolverForQuery(select, statement.getConnection());
        }
    }
    // Re-compile the plan with option "optimizeSubquery" turned on, so that enclosed
    // sub-queries can be optimized recursively.
    QueryCompiler compiler = new QueryCompiler(statement, select, resolver, targetColumns, parallelIteratorFactory, dataPlan.getContext().getSequenceManager(), true, true, dataPlans);
    return Collections.singletonList(compiler.compile());
}
Also used : JoinCompiler(org.apache.phoenix.compile.JoinCompiler) BaseQueryPlan(org.apache.phoenix.execute.BaseQueryPlan) BaseQueryPlan(org.apache.phoenix.execute.BaseQueryPlan) QueryPlan(org.apache.phoenix.compile.QueryPlan) QueryCompiler(org.apache.phoenix.compile.QueryCompiler) SequenceManager(org.apache.phoenix.compile.SequenceManager) StatementContext(org.apache.phoenix.compile.StatementContext) SelectStatement(org.apache.phoenix.parse.SelectStatement) ColumnParseNode(org.apache.phoenix.parse.ColumnParseNode) AndParseNode(org.apache.phoenix.parse.AndParseNode) ParseNode(org.apache.phoenix.parse.ParseNode) Scan(org.apache.hadoop.hbase.client.Scan) ColumnResolver(org.apache.phoenix.compile.ColumnResolver) TableRef(org.apache.phoenix.schema.TableRef)

Aggregations

QueryPlan (org.apache.phoenix.compile.QueryPlan)2 BaseQueryPlan (org.apache.phoenix.execute.BaseQueryPlan)2 SelectStatement (org.apache.phoenix.parse.SelectStatement)2 Scan (org.apache.hadoop.hbase.client.Scan)1 ColumnProjector (org.apache.phoenix.compile.ColumnProjector)1 ColumnResolver (org.apache.phoenix.compile.ColumnResolver)1 JoinCompiler (org.apache.phoenix.compile.JoinCompiler)1 QueryCompiler (org.apache.phoenix.compile.QueryCompiler)1 SequenceManager (org.apache.phoenix.compile.SequenceManager)1 StatementContext (org.apache.phoenix.compile.StatementContext)1 AndParseNode (org.apache.phoenix.parse.AndParseNode)1 ColumnParseNode (org.apache.phoenix.parse.ColumnParseNode)1 ParseNode (org.apache.phoenix.parse.ParseNode)1 PDatum (org.apache.phoenix.schema.PDatum)1 PTable (org.apache.phoenix.schema.PTable)1 TableRef (org.apache.phoenix.schema.TableRef)1