Search in sources :

Example 6 with IndexCondition

use of org.h2.index.IndexCondition in project ignite by apache.

the class H2IndexCostedBase method getCostRangeIndex.

/**
 * Get cost range.
 *
 * @param ses Session.
 * @param masks Condition masks.
 * @param rowCount Total row count.
 * @param filters Filters array.
 * @param filter Filter array index.
 * @param sortOrder Sort order.
 * @param isScanIndex Flag if current index is a scan index.
 * @param allColumnsSet All columns to select.
 * @return The cost.
 */
public long getCostRangeIndex(Session ses, int[] masks, long rowCount, TableFilter[] filters, int filter, SortOrder sortOrder, boolean isScanIndex, HashSet<Column> allColumnsSet) {
    ObjectStatisticsImpl locTblStats = (ObjectStatisticsImpl) tbl.tableStatistics();
    if (locTblStats != null)
        rowCount = locTblStats.rowCount();
    // Small increment to account statistics outdates.
    rowCount += 1000;
    TableFilter tableFilter = (filters == null) ? null : filters[filter];
    long rowsCost = rowCost(ses, tableFilter, masks, rowCount, locTblStats);
    // If the ORDER BY clause matches the ordering of this index,
    // it will be cheaper than another index, so adjust the cost
    // accordingly.
    long sortingCost = sortingCost(rowCount, filters, filter, sortOrder, isScanIndex);
    boolean skipColumnsIntersection = false;
    if (filters != null && tableFilter != null && columns != null) {
        skipColumnsIntersection = true;
        ArrayList<IndexCondition> idxConds = tableFilter.getIndexConditions();
        // Only pk with _key used.
        if (F.isEmpty(idxConds))
            skipColumnsIntersection = false;
        for (IndexCondition cond : idxConds) {
            if (cond.getColumn() == columns[0]) {
                skipColumnsIntersection = false;
                break;
            }
        }
    }
    // If we have two indexes with the same cost, and one of the indexes can
    // satisfy the query without needing to read from the primary table
    // (scan index), make that one slightly lower cost.
    boolean needsToReadFromScanIndex = true;
    if (!isScanIndex && allColumnsSet != null && !skipColumnsIntersection && !allColumnsSet.isEmpty()) {
        boolean foundAllColumnsWeNeed = true;
        for (Column c : allColumnsSet) {
            boolean found = false;
            for (Column c2 : columns) {
                if (c == c2) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                foundAllColumnsWeNeed = false;
                break;
            }
        }
        if (foundAllColumnsWeNeed)
            needsToReadFromScanIndex = false;
    }
    long rc;
    if (isScanIndex)
        rc = rowsCost + sortingCost + 20;
    else if (needsToReadFromScanIndex)
        rc = rowsCost + rowsCost + sortingCost + 20;
    else
        // The (20-x) calculation makes sure that when we pick a covering
        // index, we pick the covering index that has the smallest number of
        // columns (the more columns we have in index - the higher cost).
        // This is faster because a smaller index will fit into fewer data
        // blocks.
        rc = rowsCost + sortingCost + columns.length;
    return rc;
}
Also used : TableFilter(org.h2.table.TableFilter) Column(org.h2.table.Column) IndexColumn(org.h2.table.IndexColumn) IndexCondition(org.h2.index.IndexCondition) ObjectStatisticsImpl(org.apache.ignite.internal.processors.query.stat.ObjectStatisticsImpl)

Example 7 with IndexCondition

use of org.h2.index.IndexCondition in project ignite by apache.

the class GridH2CollocationModel method joinedWithCollocated.

/**
 * @param f Filter.
 * @return Affinity join type.
 */
@SuppressWarnings("ForLoopReplaceableByForEach")
private Affinity joinedWithCollocated(int f) {
    TableFilter tf = childFilters[f];
    GridH2Table tbl = (GridH2Table) tf.getTable();
    if (validate) {
        if (tbl.rowDescriptor().context().customAffinityMapper())
            throw customAffinityError(tbl.cacheName());
        if (F.isEmpty(tf.getIndexConditions())) {
            throw new CacheException("Failed to prepare distributed join query: " + "join condition does not use index [joinedCache=" + tbl.cacheName() + ", plan=" + tf.getSelect().getPlanSQL() + ']');
        }
    }
    IndexColumn affCol = tbl.getAffinityKeyColumn();
    boolean affKeyCondFound = false;
    if (affCol != null) {
        ArrayList<IndexCondition> idxConditions = tf.getIndexConditions();
        int affColId = affCol.column.getColumnId();
        for (int i = 0; i < idxConditions.size(); i++) {
            IndexCondition c = idxConditions.get(i);
            int colId = c.getColumn().getColumnId();
            int cmpType = c.getCompareType();
            if ((cmpType == Comparison.EQUAL || cmpType == Comparison.EQUAL_NULL_SAFE) && (colId == affColId || tbl.rowDescriptor().isKeyColumn(colId)) && c.isEvaluatable()) {
                affKeyCondFound = true;
                Expression exp = c.getExpression();
                exp = exp.getNonAliasExpression();
                if (exp instanceof ExpressionColumn) {
                    ExpressionColumn expCol = (ExpressionColumn) exp;
                    // This is one of our previous joins.
                    TableFilter prevJoin = expCol.getTableFilter();
                    if (prevJoin != null) {
                        GridH2CollocationModel cm = child(indexOf(prevJoin), true);
                        // different affinity columns from different tables.
                        if (cm != null && !cm.view) {
                            Type t = cm.type(true);
                            if (t.isPartitioned() && t.isCollocated() && isAffinityColumn(prevJoin, expCol, validate))
                                return Affinity.COLLOCATED_JOIN;
                        }
                    }
                }
            }
        }
    }
    return affKeyCondFound ? Affinity.HAS_AFFINITY_CONDITION : Affinity.NONE;
}
Also used : TableFilter(org.h2.table.TableFilter) CacheException(javax.cache.CacheException) Expression(org.h2.expression.Expression) IndexCondition(org.h2.index.IndexCondition) IndexColumn(org.h2.table.IndexColumn) ExpressionColumn(org.h2.expression.ExpressionColumn)

Example 8 with IndexCondition

use of org.h2.index.IndexCondition in project h2database by h2database.

the class TableFilter method prepare.

/**
 * Prepare reading rows. This method will remove all index conditions that
 * can not be used, and optimize the conditions.
 */
public void prepare() {
    // the indexConditions list may be modified here
    for (int i = 0; i < indexConditions.size(); i++) {
        IndexCondition condition = indexConditions.get(i);
        if (!condition.isAlwaysFalse()) {
            Column col = condition.getColumn();
            if (col.getColumnId() >= 0) {
                if (index.getColumnIndex(col) < 0) {
                    indexConditions.remove(i);
                    i--;
                }
            }
        }
    }
    if (nestedJoin != null) {
        if (SysProperties.CHECK && nestedJoin == this) {
            DbException.throwInternalError("self join");
        }
        nestedJoin.prepare();
    }
    if (join != null) {
        if (SysProperties.CHECK && join == this) {
            DbException.throwInternalError("self join");
        }
        join.prepare();
    }
    if (filterCondition != null) {
        filterCondition = filterCondition.optimize(session);
    }
    if (joinCondition != null) {
        joinCondition = joinCondition.optimize(session);
    }
}
Also used : ExpressionColumn(org.h2.expression.ExpressionColumn) IndexCondition(org.h2.index.IndexCondition)

Example 9 with IndexCondition

use of org.h2.index.IndexCondition in project h2database by h2database.

the class Table method getBestPlanItem.

/**
 * Get the best plan for the given search mask.
 *
 * @param session the session
 * @param masks per-column comparison bit masks, null means 'always false',
 *              see constants in IndexCondition
 * @param filters all joined table filters
 * @param filter the current table filter index
 * @param sortOrder the sort order
 * @param allColumnsSet the set of all columns
 * @return the plan item
 */
public PlanItem getBestPlanItem(Session session, int[] masks, TableFilter[] filters, int filter, SortOrder sortOrder, HashSet<Column> allColumnsSet) {
    PlanItem item = new PlanItem();
    item.setIndex(getScanIndex(session));
    item.cost = item.getIndex().getCost(session, null, filters, filter, null, allColumnsSet);
    Trace t = session.getTrace();
    if (t.isDebugEnabled()) {
        t.debug("Table      :     potential plan item cost {0} index {1}", item.cost, item.getIndex().getPlanSQL());
    }
    ArrayList<Index> indexes = getIndexes();
    IndexHints indexHints = getIndexHints(filters, filter);
    if (indexes != null && masks != null) {
        for (int i = 1, size = indexes.size(); i < size; i++) {
            Index index = indexes.get(i);
            if (isIndexExcludedByHints(indexHints, index)) {
                continue;
            }
            double cost = index.getCost(session, masks, filters, filter, sortOrder, allColumnsSet);
            if (t.isDebugEnabled()) {
                t.debug("Table      :     potential plan item cost {0} index {1}", cost, index.getPlanSQL());
            }
            if (cost < item.cost) {
                item.cost = cost;
                item.setIndex(index);
            }
        }
    }
    return item;
}
Also used : Trace(org.h2.message.Trace) Index(org.h2.index.Index) Constraint(org.h2.constraint.Constraint)

Example 10 with IndexCondition

use of org.h2.index.IndexCondition in project ignite by apache.

the class CollocationModel method joinedWithCollocated.

/**
 * @param f Filter.
 * @return Affinity join type.
 */
@SuppressWarnings("ForLoopReplaceableByForEach")
private CollocationModelAffinity joinedWithCollocated(int f) {
    TableFilter tf = childFilters[f];
    GridH2Table tbl = (GridH2Table) tf.getTable();
    if (validate) {
        if (tbl.isCustomAffinityMapper())
            throw customAffinityError(tbl.cacheName());
        if (F.isEmpty(tf.getIndexConditions())) {
            throw new CacheException("Failed to prepare distributed join query: " + "join condition does not use index [joinedCache=" + tbl.cacheName() + ", plan=" + tf.getSelect().getPlanSQL() + ']');
        }
    }
    IndexColumn affCol = tbl.getAffinityKeyColumn();
    boolean affKeyCondFound = false;
    if (affCol != null) {
        ArrayList<IndexCondition> idxConditions = tf.getIndexConditions();
        int affColId = affCol.column.getColumnId();
        for (int i = 0; i < idxConditions.size(); i++) {
            IndexCondition c = idxConditions.get(i);
            int colId = c.getColumn().getColumnId();
            int cmpType = c.getCompareType();
            if ((cmpType == Comparison.EQUAL || cmpType == Comparison.EQUAL_NULL_SAFE) && (colId == affColId || tbl.rowDescriptor().isKeyColumn(colId)) && c.isEvaluatable()) {
                affKeyCondFound = true;
                Expression exp = c.getExpression();
                exp = exp.getNonAliasExpression();
                if (exp instanceof ExpressionColumn) {
                    ExpressionColumn expCol = (ExpressionColumn) exp;
                    // This is one of our previous joins.
                    TableFilter prevJoin = expCol.getTableFilter();
                    if (prevJoin != null) {
                        CollocationModel cm = child(indexOf(prevJoin), true);
                        // different affinity columns from different tables.
                        if (cm != null && !cm.view) {
                            CollocationModelType t = cm.type(true);
                            if (t.isPartitioned() && t.isCollocated() && isAffinityColumn(prevJoin, expCol, validate))
                                return CollocationModelAffinity.COLLOCATED_JOIN;
                        }
                    }
                }
            }
        }
    }
    return affKeyCondFound ? CollocationModelAffinity.HAS_AFFINITY_CONDITION : CollocationModelAffinity.NONE;
}
Also used : TableFilter(org.h2.table.TableFilter) CacheException(javax.cache.CacheException) Expression(org.h2.expression.Expression) GridH2Table(org.apache.ignite.internal.processors.query.h2.opt.GridH2Table) IndexCondition(org.h2.index.IndexCondition) IndexColumn(org.h2.table.IndexColumn) ExpressionColumn(org.h2.expression.ExpressionColumn)

Aggregations

IndexCondition (org.h2.index.IndexCondition)7 IndexColumn (org.h2.table.IndexColumn)5 TableFilter (org.h2.table.TableFilter)5 ExpressionColumn (org.h2.expression.ExpressionColumn)3 Column (org.h2.table.Column)3 CacheException (javax.cache.CacheException)2 Expression (org.h2.expression.Expression)2 GridH2Table (org.apache.ignite.internal.processors.query.h2.opt.GridH2Table)1 ObjectStatisticsImpl (org.apache.ignite.internal.processors.query.stat.ObjectStatisticsImpl)1 Constraint (org.h2.constraint.Constraint)1 Index (org.h2.index.Index)1 IndexLookupBatch (org.h2.index.IndexLookupBatch)1 Trace (org.h2.message.Trace)1 SortOrder (org.h2.result.SortOrder)1 StatementBuilder (org.h2.util.StatementBuilder)1 Value (org.h2.value.Value)1