>From Vijay Sarathy <[email protected]>:
Vijay Sarathy has uploaded this change for review. (
https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/18236 )
Change subject: [ASTERIXDB-3377][COMP]: CBO choosing wrong index
......................................................................
[ASTERIXDB-3377][COMP]: CBO choosing wrong index
Change-Id: I81a6dcca634d3d30f0b101baabe4093fb01123d0
---
M
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/Stats.java
M
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/JoinEnum.java
M
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/JoinNode.java
3 files changed, 82 insertions(+), 29 deletions(-)
git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb
refs/changes/36/18236/1
diff --git
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/JoinEnum.java
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/JoinEnum.java
index e419eea..951648a 100644
---
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/JoinEnum.java
+++
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/JoinEnum.java
@@ -30,6 +30,7 @@
import org.apache.asterix.common.annotations.IndexedNLJoinExpressionAnnotation;
import
org.apache.asterix.common.annotations.SecondaryIndexSearchPreferenceAnnotation;
+import
org.apache.asterix.common.annotations.SkipSecondaryIndexSearchExpressionAnnotation;
import org.apache.asterix.common.exceptions.AsterixException;
import org.apache.asterix.common.exceptions.ErrorCode;
import org.apache.asterix.metadata.declared.DataSource;
@@ -384,6 +385,29 @@
return false;
}
+ public SkipSecondaryIndexSearchExpressionAnnotation
findSkipIndexHint(AbstractFunctionCallExpression condition) {
+ if
(condition.getFunctionIdentifier().equals(AlgebricksBuiltinFunctions.AND)) {
+ for (int i = 0; i < condition.getArguments().size(); i++) {
+ ILogicalExpression expr =
condition.getArguments().get(i).getValue();
+ if
(expr.getExpressionTag().equals(LogicalExpressionTag.FUNCTION_CALL)) {
+ AbstractFunctionCallExpression AFCexpr =
(AbstractFunctionCallExpression) expr;
+ SkipSecondaryIndexSearchExpressionAnnotation skipAnno =
+
AFCexpr.getAnnotation(SkipSecondaryIndexSearchExpressionAnnotation.class);
+ if (skipAnno != null) {
+ return skipAnno;
+ }
+ }
+ }
+ } else if
(condition.getExpressionTag().equals(LogicalExpressionTag.FUNCTION_CALL)) {
+ SkipSecondaryIndexSearchExpressionAnnotation skipAnno =
+
condition.getAnnotation(SkipSecondaryIndexSearchExpressionAnnotation.class);
+ if (skipAnno != null) {
+ return skipAnno;
+ }
+ }
+ return null;
+ }
+
protected int findJoinNodeIndexByName(String name) {
for (int i = 1; i <= this.numberOfTerms; i++) {
if (name.equals(jnArray[i].datasetNames.get(0))) {
diff --git
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/JoinNode.java
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/JoinNode.java
index 4543190..fe04a68 100644
---
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/JoinNode.java
+++
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/JoinNode.java
@@ -21,6 +21,7 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
@@ -546,9 +547,20 @@
for (int i = 0; i < IndexCostInfo.size(); i++) {
if (IndexCostInfo.get(i).second == -1.0) {
AbstractFunctionCallExpression afce =
IndexCostInfo.get(i).third;
- // this index has to be skipped, so find the corresponding
expression
- EnumerateJoinsRule.setAnnotation(afce,
SkipSecondaryIndexSearchExpressionAnnotation
-
.newInstance(Collections.singleton(IndexCostInfo.get(i).first.getIndexName())));
+ SkipSecondaryIndexSearchExpressionAnnotation skipAnno =
joinEnum.findSkipIndexHint(afce);
+ Collection<String> indexNames = null;
+ if (skipAnno != null) {
+ indexNames = skipAnno.getIndexNames();
+ }
+ if (indexNames == null) {
+ // this index has to be skipped, so find the corresponding
expression
+ EnumerateJoinsRule.setAnnotation(afce,
SkipSecondaryIndexSearchExpressionAnnotation
+
.newInstance(Collections.singleton(IndexCostInfo.get(i).first.getIndexName())));
+ } else {
+ indexNames.add(IndexCostInfo.get(i).first.getIndexName());
+ EnumerateJoinsRule.setAnnotation(afce,
+
SkipSecondaryIndexSearchExpressionAnnotation.newInstance(indexNames));
+ }
}
}
}
diff --git
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/Stats.java
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/Stats.java
index 254d364..785da69 100644
---
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/Stats.java
+++
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/Stats.java
@@ -446,33 +446,41 @@
List<List<IAObject>> result;
parent.getInputs().get(0).setValue(deepCopyofScan);
- if (numSubplans == 1 && nonSubplanSelects == 0) {
- AggregateOperator aggOp = findAggOp(selOp, exp);
- if (aggOp.getExpressions().size() > 1) {
- // ANY and EVERY IN query; for selectivity purposes, we need
to transform this into a ANY IN query
- SelectOperator newSelOp = (SelectOperator)
OperatorManipulationUtil.bottomUpCopyOperators(selOp);
- aggOp = findAggOp(newSelOp, exp);
- ILogicalOperator input = aggOp.getInputs().get(0).getValue();
- SelectOperator condition = (SelectOperator)
OperatorManipulationUtil
-
.bottomUpCopyOperators(AbstractOperatorFromSubplanRewrite.getSelectFromPlan(aggOp));
- //push this condition below aggOp.
- aggOp.getInputs().get(0).setValue(condition);
- condition.getInputs().get(0).setValue(input);
- ILogicalExpression newExp2 =
newSelOp.getCondition().getValue();
- if (newExp2.getExpressionTag() ==
LogicalExpressionTag.FUNCTION_CALL) {
- AbstractFunctionCallExpression afce =
(AbstractFunctionCallExpression) newExp2;
-
afce.getArguments().get(1).setValue(ConstantExpression.TRUE);
- }
- result = runSamplingQuery(optCtx, newSelOp); // no need to
switch anything
- } else {
- result = runSamplingQuery(optCtx, selOp);
- }
- } else {
- SelectOperator selOp2 = findSelectOpWithExpr(selOp, exp);
- List<ILogicalExpression> selExprs;
- selExprs = storeSelectConditionsAndMakeThemTrue(selOp, selOp2); //
all these will be marked true and will be resorted later.
+
+ if (numSelects == 1 && numSubplans == 0) { // just switch the
predicates; the simplest case. There should be no other case if subplans were
canonical
+ ILogicalExpression saveExprs = selOp.getCondition().getValue();
+ selOp.getCondition().setValue(exp);
result = runSamplingQuery(optCtx, selOp);
- restoreAllSelectConditions(selOp, selExprs, selOp2);
+ selOp.getCondition().setValue(saveExprs);
+ } else {
+ if (numSubplans == 1 && nonSubplanSelects == 0) {
+ AggregateOperator aggOp = findAggOp(selOp, exp);
+ if (aggOp.getExpressions().size() > 1) {
+ // ANY and EVERY IN query; for selectivity purposes, we
need to transform this into a ANY IN query
+ SelectOperator newSelOp = (SelectOperator)
OperatorManipulationUtil.bottomUpCopyOperators(selOp);
+ aggOp = findAggOp(newSelOp, exp);
+ ILogicalOperator input =
aggOp.getInputs().get(0).getValue();
+ SelectOperator condition = (SelectOperator)
OperatorManipulationUtil
+
.bottomUpCopyOperators(AbstractOperatorFromSubplanRewrite.getSelectFromPlan(aggOp));
+ //push this condition below aggOp.
+ aggOp.getInputs().get(0).setValue(condition);
+ condition.getInputs().get(0).setValue(input);
+ ILogicalExpression newExp2 =
newSelOp.getCondition().getValue();
+ if (newExp2.getExpressionTag() ==
LogicalExpressionTag.FUNCTION_CALL) {
+ AbstractFunctionCallExpression afce =
(AbstractFunctionCallExpression) newExp2;
+
afce.getArguments().get(1).setValue(ConstantExpression.TRUE);
+ }
+ result = runSamplingQuery(optCtx, newSelOp); // no need to
switch anything
+ } else {
+ result = runSamplingQuery(optCtx, selOp);
+ }
+ } else {
+ SelectOperator selOp2 = findSelectOpWithExpr(selOp, exp);
+ List<ILogicalExpression> selExprs;
+ selExprs = storeSelectConditionsAndMakeThemTrue(selOp,
selOp2); // all these will be marked true and will be resorted later.
+ result = runSamplingQuery(optCtx, selOp);
+ restoreAllSelectConditions(selOp, selExprs, selOp2);
+ }
}
double predicateCardinality = findPredicateCardinality(result, false);
--
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/18236
To unsubscribe, or for help writing mail filters, visit
https://asterix-gerrit.ics.uci.edu/settings
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Change-Id: I81a6dcca634d3d30f0b101baabe4093fb01123d0
Gerrit-Change-Number: 18236
Gerrit-PatchSet: 1
Gerrit-Owner: Vijay Sarathy <[email protected]>
Gerrit-MessageType: newchange