use of org.h2.table.TableFilter in project ignite by apache.
the class GridH2ProxyIndex method createLookupBatch.
/**
* {@inheritDoc}
*/
@Override
public IndexLookupBatch createLookupBatch(TableFilter[] filters, int filter) {
IndexLookupBatch batch = idx.createLookupBatch(filters, filter);
if (batch == null)
return null;
GridH2RowDescriptor rowDesc = ((GridH2Table) idx.getTable()).rowDescriptor();
return new ProxyDistributedLookupBatch(batch, rowDesc);
}
use of org.h2.table.TableFilter 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.table.TableFilter in project ignite by apache.
the class H2IndexCostedBase method rowCost.
/**
* Row cost calculation.
*
* @param ses Session.
* @param filter Table filter.
* @param masks Masks array.
* @param rowCount Total rows count.
* @param locTblStats Local table statistics.
* @return Row cost.
*/
private long rowCost(Session ses, TableFilter filter, int[] masks, long rowCount, ObjectStatisticsImpl locTblStats) {
double totalCardinality = 0;
long rowsCost = rowCount;
if (masks != null) {
int i = 0, len = columns.length;
while (i < len) {
Column column = columns[i++];
ColumnStatistics colStats = getColumnStatistics(locTblStats, column);
int index = column.getColumnId();
int mask = masks[index];
if (isByteFlag(mask, IndexCondition.EQUALITY)) {
if (i == len && getIndexType().isUnique()) {
rowsCost = 3;
break;
}
// Estimate by is null
Value equalValue = getEqualValue(ses, column, filter);
Boolean equalNull = (equalValue == null) ? null : equalValue.getType() == Value.NULL;
rowCount = getColumnSize(colStats, rowCount, equalNull);
if (colStats != null && equalNull == Boolean.TRUE) {
rowsCost = Math.min(5 + Math.max(Math.round(rowsCost * nulls(colStats)), 1), rowsCost - (i > 0 ? 1 : 0));
continue;
}
if (colStats != null && equalNull == Boolean.FALSE)
rowsCost = Math.max(Math.round(rowsCost * (1 - nulls(colStats))), 1);
long distinctRows;
if (colStats == null) {
double cardinality = (double) column.getSelectivity() / 100;
totalCardinality = 1 - (1 - totalCardinality) * (1 - cardinality);
distinctRows = Math.round((double) rowCount * totalCardinality);
} else {
double cardinality;
long nonNulls = colStats.total() - colStats.nulls();
if (nonNulls == 0)
cardinality = 1;
else
cardinality = (double) colStats.distinct() / nonNulls;
totalCardinality = 1 - (1 - totalCardinality) * (1 - cardinality);
distinctRows = Math.round(rowCount * totalCardinality);
}
if (distinctRows <= 0)
distinctRows = 1;
rowsCost = Math.min(5 + Math.max(rowsCost / distinctRows, 1), rowsCost - (i > 0 ? 1 : 0));
} else if (isByteFlag(mask, IndexCondition.RANGE) || isByteFlag(mask, IndexCondition.START) || isByteFlag(mask, IndexCondition.END)) {
Value min = getStartValue(ses, column, filter);
Value max = getEndValue(ses, column, filter);
int percent = estimatePercent(colStats, min, max);
rowsCost = Math.min(5 + rowsCost * percent / 100, rowsCost - (i > 0 ? 1 : 0));
break;
} else if (isNullFilter(ses, column, filter)) {
if (colStats != null)
rowsCost = Math.min(5 + colStats.nulls(), rowsCost - (i > 0 ? 1 : 0));
break;
} else if (isNotNullFilter(ses, column, filter)) {
if (colStats != null)
rowsCost = Math.min(5 + colStats.total() - colStats.nulls(), rowsCost - (i > 0 ? 1 : 0));
break;
} else
break;
}
}
return rowsCost;
}
use of org.h2.table.TableFilter in project ignite by apache.
the class CollocationModel method buildCollocationModel.
/**
* @param ctx Splitter context.
* @param info Sub-query info.
* @param filters Filters.
* @param filter Filter.
* @param validate Query validation flag.
* @return Collocation.
*/
private static CollocationModel buildCollocationModel(SplitterContext ctx, SubQueryInfo info, TableFilter[] filters, int filter, boolean validate) {
CollocationModel cm;
if (info != null) {
// Go up until we reach the root query.
cm = buildCollocationModel(ctx, info.getUpper(), info.getFilters(), info.getFilter(), validate);
} else {
// We are at the root query.
cm = ctx.collocationModel();
if (cm == null) {
cm = createChildModel(null, -1, null, true, validate);
ctx.collocationModel(cm);
}
}
if (filters == null)
return cm;
assert cm.view;
Select select = filters[0].getSelect();
// For sub-queries we will drop collocation models, so that they will be recalculated anyways.
if (cm.select != null && cm.select != select) {
List<CollocationModel> unions = cm.getOrCreateUnions();
// Start with 1 because at 0 it always will be c.
for (int i = 1; i < unions.size(); i++) {
CollocationModel u = unions.get(i);
if (u.select == select) {
cm = u;
break;
}
}
// Nothing was found, need to create new child in union.
if (cm.select != select)
cm = createChildModel(cm.upper, cm.filter, unions, true, validate);
}
cm.childFilters(filters);
return cm.child(filter, true);
}
use of org.h2.table.TableFilter in project ignite by apache.
the class CollocationModel method buildCollocationModel.
/**
* @param upper Upper.
* @param filter Filter.
* @param qry Query.
* @param unions Unions.
* @param validate Query validation flag.
* @return Built model.
*/
private static CollocationModel buildCollocationModel(CollocationModel upper, int filter, Query qry, List<CollocationModel> unions, boolean validate) {
if (qry.isUnion()) {
if (unions == null)
unions = new ArrayList<>();
SelectUnion union = (SelectUnion) qry;
CollocationModel left = buildCollocationModel(upper, filter, union.getLeft(), unions, validate);
CollocationModel right = buildCollocationModel(upper, filter, union.getRight(), unions, validate);
assert left != null;
assert right != null;
return upper != null ? upper : left;
}
Select select = (Select) qry;
List<TableFilter> list = new ArrayList<>();
for (TableFilter f = select.getTopTableFilter(); f != null; f = f.getJoin()) list.add(f);
TableFilter[] filters = list.toArray(EMPTY_FILTERS);
CollocationModel cm = createChildModel(upper, filter, unions, true, validate);
cm.childFilters(filters);
for (int i = 0; i < filters.length; i++) {
TableFilter f = filters[i];
if (f.getTable().isView())
buildCollocationModel(cm, i, getSubQuery(f), null, validate);
else if (f.getTable() instanceof GridH2Table)
createChildModel(cm, i, null, false, validate);
}
return upper != null ? upper : cm;
}
Aggregations