>From Vijay Sarathy <[email protected]>: Vijay Sarathy has submitted this change. ( 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 Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/18236 Integration-Tests: Jenkins <[email protected]> Tested-by: Jenkins <[email protected]> Reviewed-by: <[email protected]> Reviewed-by: Vijay Sarathy <[email protected]> --- M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/Stats.java M asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-16.plan 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 4 files changed, 90 insertions(+), 31 deletions(-) Approvals: [email protected]: Looks good to me, but someone else must approve Vijay Sarathy: Looks good to me, approved Jenkins: Verified; Verified Anon. E. Moose #1000171: 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..37212ba 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,8 +21,10 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -546,9 +548,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 = new HashSet<>(); + if (skipAnno != null && skipAnno.getIndexNames() != null) { + indexNames.addAll(skipAnno.getIndexNames()); + } + if (indexNames.isEmpty()) { + // 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); diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-16.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-16.plan index 00ba0d7..725e81e 100644 --- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-16.plan +++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-16.plan @@ -9,11 +9,11 @@ -- ONE_TO_ONE_EXCHANGE |PARTITIONED| -- BTREE_SEARCH (test.tenk.tenk) |PARTITIONED| -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- STABLE_SORT [$$31(ASC)] |PARTITIONED| + -- STABLE_SORT [$$28(ASC)] |PARTITIONED| -- ONE_TO_ONE_EXCHANGE |PARTITIONED| -- STREAM_PROJECT |PARTITIONED| -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- BTREE_SEARCH (test.tenk.idx_1k_2k) |PARTITIONED| + -- BTREE_SEARCH (test.tenk.idx_2k) |PARTITIONED| -- ONE_TO_ONE_EXCHANGE |PARTITIONED| -- ASSIGN |PARTITIONED| -- EMPTY_TUPLE_SOURCE |PARTITIONED| -- 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: 3 Gerrit-Owner: Vijay Sarathy <[email protected]> Gerrit-Reviewer: Anon. E. Moose #1000171 Gerrit-Reviewer: Jenkins <[email protected]> Gerrit-Reviewer: Vijay Sarathy <[email protected]> Gerrit-Reviewer: [email protected] Gerrit-MessageType: merged
