提交 87562a00 authored 作者: Sergi Vladykin's avatar Sergi Vladykin

Choose minimal covering index for MIN/MAX and DISTINCT

上级 cb88fe35
......@@ -889,7 +889,7 @@ public class Select extends Query {
Column column = ((ExpressionColumn) expr).getColumn();
int selectivity = column.getSelectivity();
Index columnIndex = topTableFilter.getTable().
getIndexForColumn(column);
getIndexForColumn(column, false, true);
if (columnIndex != null &&
selectivity != Constants.SELECTIVITY_DEFAULT &&
selectivity < 20) {
......
......@@ -287,7 +287,7 @@ public class Aggregate extends Expression {
case MIN:
case MAX:
boolean first = type == MIN;
Index index = getColumnIndex();
Index index = getMinMaxColumnIndex();
int sortType = index.getIndexColumns()[0].sortType;
if ((sortType & SortOrder.DESCENDING) != 0) {
first = !first;
......@@ -575,14 +575,14 @@ public class Aggregate extends Expression {
return text + StringUtils.enclose(on.getSQL());
}
private Index getColumnIndex() {
private Index getMinMaxColumnIndex() {
if (on instanceof ExpressionColumn) {
ExpressionColumn col = (ExpressionColumn) on;
Column column = col.getColumn();
TableFilter filter = col.getTableFilter();
if (filter != null) {
Table table = filter.getTable();
Index index = table.getIndexForColumn(column);
Index index = table.getIndexForColumn(column, true, false);
return index;
}
}
......@@ -602,7 +602,7 @@ public class Aggregate extends Expression {
return visitor.getTable().canGetRowCount();
case MIN:
case MAX:
Index index = getColumnIndex();
Index index = getMinMaxColumnIndex();
return index != null;
default:
return false;
......
......@@ -1050,22 +1050,35 @@ public abstract class Table extends SchemaObjectBase {
* This method returns null if no matching index is found.
*
* @param column the column
* @param needGetFirstOrLast if the returned index must be able
* to do {@link Index#canGetFirstOrLast()}
* @param needFindNext if the returned index must be able to do
* {@link Index#findNext(Session, SearchRow, SearchRow)}
* @return the index or null
*/
public Index getIndexForColumn(Column column) {
public Index getIndexForColumn(Column column,
boolean needGetFirstOrLast, boolean needFindNext) {
ArrayList<Index> indexes = getIndexes();
Index result = null;
if (indexes != null) {
for (int i = 1, size = indexes.size(); i < size; i++) {
Index index = indexes.get(i);
if (index.canGetFirstOrLast()) {
int idx = index.getColumnIndex(column);
if (idx == 0) {
return index;
if (needGetFirstOrLast && !index.canGetFirstOrLast()) {
continue;
}
if (needFindNext && !index.canFindNext()) {
continue;
}
int idx = index.getColumnIndex(column);
// choose the minimal covering index with the needed first column
// to work consistently with execution plan from Optimizer
if (idx == 0 && (result == null ||
result.getColumns().length > index.getColumns().length)) {
result = index;
}
}
return null;
}
return result;
}
public boolean getOnCommitDrop() {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论