提交 dc268c8b authored 作者: Noel Grandin's avatar Noel Grandin

format and remove some debug

上级 1e48ee39
...@@ -160,47 +160,47 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index { ...@@ -160,47 +160,47 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
* @param sortOrder the sort order * @param sortOrder the sort order
* @return the estimated cost * @return the estimated cost
*/ */
protected final long getCostRangeIndex(int[] masks, long rowCount, protected final long getCostRangeIndex(int[] masks, long rowCount, TableFilter[] filters, int filter,
TableFilter[] filters, int filter, SortOrder sortOrder, boolean isScanIndex) { SortOrder sortOrder, boolean isScanIndex) {
rowCount += Constants.COST_ROW_OFFSET; rowCount += Constants.COST_ROW_OFFSET;
int totalSelectivity = 0; int totalSelectivity = 0;
long rowsCost = rowCount; long rowsCost = rowCount;
if (masks != null) { if (masks != null) {
for (int i = 0, len = columns.length; i < len; i++) { for (int i = 0, len = columns.length; i < len; i++) {
Column column = columns[i]; Column column = columns[i];
int index = column.getColumnId(); int index = column.getColumnId();
int mask = masks[index]; int mask = masks[index];
if ((mask & IndexCondition.EQUALITY) == IndexCondition.EQUALITY) { if ((mask & IndexCondition.EQUALITY) == IndexCondition.EQUALITY) {
if (i == columns.length - 1 && getIndexType().isUnique()) { if (i == columns.length - 1 && getIndexType().isUnique()) {
rowsCost = 3; rowsCost = 3;
break; break;
} }
totalSelectivity = 100 - ((100 - totalSelectivity) * totalSelectivity = 100 - ((100 - totalSelectivity) * (100 - column.getSelectivity()) / 100);
(100 - column.getSelectivity()) / 100); long distinctRows = rowCount * totalSelectivity / 100;
long distinctRows = rowCount * totalSelectivity / 100; if (distinctRows <= 0) {
if (distinctRows <= 0) { distinctRows = 1;
distinctRows = 1; }
} rowsCost = 2 + Math.max(rowCount / distinctRows, 1);
rowsCost = 2 + Math.max(rowCount / distinctRows, 1); } else if ((mask & IndexCondition.RANGE) == IndexCondition.RANGE) {
} else if ((mask & IndexCondition.RANGE) == IndexCondition.RANGE) { rowsCost = 2 + rowCount / 4;
rowsCost = 2 + rowCount / 4; break;
break; } else if ((mask & IndexCondition.START) == IndexCondition.START) {
} else if ((mask & IndexCondition.START) == IndexCondition.START) { rowsCost = 2 + rowCount / 3;
rowsCost = 2 + rowCount / 3; break;
break; } else if ((mask & IndexCondition.END) == IndexCondition.END) {
} else if ((mask & IndexCondition.END) == IndexCondition.END) { rowsCost = rowCount / 3;
rowsCost = rowCount / 3; break;
break; } else {
} else { break;
break; }
} }
}
} }
// If the ORDER BY clause matches the ordering of this index, // If the ORDER BY clause matches the ordering of this index,
// it will be cheaper than another index, so adjust the cost accordingly. // it will be cheaper than another index, so adjust the cost
// accordingly.
long sortingCost = 0; long sortingCost = 0;
if (sortOrder != null) { if (sortOrder != null) {
sortingCost = 100 + rowCount/10; sortingCost = 100 + rowCount / 10;
} }
if (sortOrder != null && !isScanIndex) { if (sortOrder != null && !isScanIndex) {
boolean sortOrderMatches = true; boolean sortOrderMatches = true;
...@@ -239,43 +239,44 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index { ...@@ -239,43 +239,44 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
sortingCost = 100 - coveringCount; sortingCost = 100 - coveringCount;
} }
} }
// If we have two indexes with the same cost, and one of the indexes can satisfy the query // If we have two indexes with the same cost, and one of the indexes can
// without needing to read from the primary table, make that one slightly lower cost. // satisfy the query without needing to read from the primary table,
// make that one slightly lower cost.
boolean needsToReadFromScanIndex = true; boolean needsToReadFromScanIndex = true;
if (!isScanIndex) { if (!isScanIndex) {
HashSet<Column> set1 = New.hashSet(); HashSet<Column> set1 = New.hashSet();
for (int i = 0; i < filters.length; i++) { for (int i = 0; i < filters.length; i++) {
if (filters[i].getSelect() != null) { if (filters[i].getSelect() != null) {
filters[i].getSelect().isEverything(ExpressionVisitor.getColumnsVisitor(set1)); filters[i].getSelect().isEverything(ExpressionVisitor.getColumnsVisitor(set1));
} }
} }
if (!set1.isEmpty()) { if (!set1.isEmpty()) {
HashSet<Column> set2 = New.hashSet(); HashSet<Column> set2 = New.hashSet();
for (Column c : set1) { for (Column c : set1) {
if (c.getTable() == getTable()) { if (c.getTable() == getTable()) {
set2.add(c); set2.add(c);
} }
} }
set2.removeAll(Arrays.asList(columns)); set2.removeAll(Arrays.asList(columns));
if (set2.isEmpty()) { if (set2.isEmpty()) {
needsToReadFromScanIndex = false; needsToReadFromScanIndex = false;
} }
} }
} }
long rc; long rc;
if (isScanIndex) { if (isScanIndex) {
rc = rowsCost + sortingCost + 20; rc = rowsCost + sortingCost + 20;
} else if (needsToReadFromScanIndex) { } else if (needsToReadFromScanIndex) {
rc = rowsCost + rowsCost + sortingCost + 20; rc = rowsCost + rowsCost + sortingCost + 20;
} else { } 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. This is faster because a smaller index will fit into * The (20-x) calculation makes sure that when we pick a covering
* fewer data blocks. * index, we pick the covering index that has the smallest number of
*/ * columns. This is faster because a smaller index will fit into
rc = rowsCost + sortingCost + (20 - columns.length); * fewer data blocks.
*/
rc = rowsCost + sortingCost + (20 - columns.length);
} }
getDatabase().getTrace(0).debug("needsToReadFromScanIndex " + needsToReadFromScanIndex + " isScanIndex "
+ isScanIndex + " rowsCost " + rowsCost + " rowCount " + rowCount + " sortingCost " + sortingCost + " rc " +rc);
return rc; return rc;
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论