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