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