Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improving search by compound indexes. #3915

Merged
merged 12 commits into from
Nov 27, 2023
31 changes: 29 additions & 2 deletions h2/src/main/org/h2/expression/condition/ConditionIn.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
package org.h2.expression.condition;

import java.util.ArrayList;
import java.util.List;

import org.h2.engine.SessionLocal;
import org.h2.expression.Expression;
import org.h2.expression.ExpressionColumn;
Expand Down Expand Up @@ -165,12 +167,37 @@ public void createIndexConditions(SessionLocal session, TableFilter filter) {
} else if (left instanceof ExpressionList) {
ExpressionList list = (ExpressionList) left;
if (!list.isArray()) {
createIndexConditions(filter, list);
// First we create a compound index condition.
createCompoundIndexCondition(filter);
// If there is no compound index, then the TableFilter#prepare() method will drop this condition.
// Then we create a unique index condition for each column.
createUniqueIndexConditions(filter, list);
// If there are two or more index conditions, IndexCursor will only use the first one.
// See: IndexCursor#canUseIndexForIn(Column)
}
}
}

private void createIndexConditions(TableFilter filter, ExpressionList list) {
/**
* Creates a compound index condition containing every item in the expression list.
* @see IndexCondition#getCompoundInList(ExpressionList, List)
*/
private void createCompoundIndexCondition(TableFilter filter) {
// We do not check filter here, because the IN condition can contain columns from multiple tables.
ExpressionVisitor visitor = ExpressionVisitor.getNotFromResolverVisitor(filter);
for (Expression e : valueList) {
if (!e.isEverything(visitor)) {
return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (!e.isEverything(visitor)) {
    return;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}
}
filter.addIndexCondition(IndexCondition.getCompoundInList((ExpressionList) left, valueList));
}

/**
* Creates a unique index condition for every item in the expression list.
* @see IndexCondition#getInList(ExpressionColumn, List)
*/
private void createUniqueIndexConditions(TableFilter filter, ExpressionList list) {
int c = list.getSubexpressionCount();
for (int i = 0; i < c; i++) {
Expression e = list.getSubexpression(i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package org.h2.expression.condition;

import java.util.ArrayList;
import java.util.List;
import java.util.TreeSet;

import org.h2.engine.SessionLocal;
Expand Down Expand Up @@ -139,12 +140,37 @@ public void createIndexConditions(SessionLocal session, TableFilter filter) {
} else if (left instanceof ExpressionList) {
ExpressionList list = (ExpressionList) left;
if (!list.isArray()) {
createIndexConditions(filter, list);
// First we create a compound index condition.
createCompoundIndexCondition(filter);
// If there is no compound index, then the TableFilter#prepare() method will drop this condition.
// Then we create a unique index condition for each column.
createUniqueIndexConditions(filter, list);
// If there are two or more index conditions, IndexCursor will only use the first one.
// See: IndexCursor#canUseIndexForIn(Column)
}
}
}

private void createIndexConditions(TableFilter filter, ExpressionList list) {
/**
* Creates a compound index condition containing every item in the expression list.
* @see IndexCondition#getCompoundInList(ExpressionList, List)
*/
private void createCompoundIndexCondition(TableFilter filter) {
// We do not check filter here, because the IN condition can contain columns from multiple tables.
ExpressionVisitor visitor = ExpressionVisitor.getNotFromResolverVisitor(filter);
for (Expression e : valueList) {
if (!e.isEverything(visitor)) {
return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}
}
filter.addIndexCondition(IndexCondition.getCompoundInList((ExpressionList) left, valueList));
}

/**
* Creates a unique index condition for every item in the expression list.
* @see IndexCondition#getInList(ExpressionColumn, List)
*/
private void createUniqueIndexConditions(TableFilter filter, ExpressionList list) {
int c = list.getSubexpressionCount();
for (int i = 0; i < c; i++) {
Expression e = list.getSubexpression(i);
Expand Down