>From Shahrzad Shirazi <[email protected]>:
Shahrzad Shirazi has uploaded this change for review. (
https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/21080?usp=email )
Change subject: WIP: fix skip-index for CBO
......................................................................
WIP: fix skip-index for CBO
Change-Id: I0baf0888eb9834fb92f7ce77b8457e76ea0bdee3
---
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
M
asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index-selection/hints-skip-index/hints-skip-index-12.sqlpp
A
asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q22.plan
M
hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/config/AlgebricksConfig.java
5 files changed, 156 insertions(+), 7 deletions(-)
git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb
refs/changes/80/21080/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 16518c2..bbc91bf 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
@@ -23,6 +23,7 @@
import java.time.LocalDateTime;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -423,18 +424,35 @@
}
public SkipSecondaryIndexSearchExpressionAnnotation
findSkipIndexHint(AbstractFunctionCallExpression condition) {
- if
(condition.getFunctionIdentifier().equals(AlgebricksBuiltinFunctions.AND)) {
+ if
(condition.getFunctionIdentifier().equals(AlgebricksBuiltinFunctions.AND)
+ ||
condition.getFunctionIdentifier().equals(AlgebricksBuiltinFunctions.OR)) {
+ Collection<String> skippedIndexNames = new HashSet<>();
+ boolean found = false;
+
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;
+ if (skipAnno != null && skipAnno.getIndexNames() != null) {
+ skippedIndexNames.addAll(skipAnno.getIndexNames());
+ found = true;
+ }
+ // Recursively check nested expressions
+ if
(AFCexpr.getFunctionIdentifier().equals(AlgebricksBuiltinFunctions.AND)
+ ||
AFCexpr.getFunctionIdentifier().equals(AlgebricksBuiltinFunctions.OR)) {
+ SkipSecondaryIndexSearchExpressionAnnotation
nestedSkipAnno = findSkipIndexHint(AFCexpr);
+ if (nestedSkipAnno != null &&
nestedSkipAnno.getIndexNames() != null) {
+
skippedIndexNames.addAll(nestedSkipAnno.getIndexNames());
+ found = true;
+ }
}
}
}
+ if (found) {
+ return
SkipSecondaryIndexSearchExpressionAnnotation.newInstance(skippedIndexNames);
+ }
} else if
(condition.getExpressionTag().equals(LogicalExpressionTag.FUNCTION_CALL)) {
SkipSecondaryIndexSearchExpressionAnnotation skipAnno =
condition.getAnnotation(SkipSecondaryIndexSearchExpressionAnnotation.class);
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 cb961b3..e35e422 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
@@ -701,8 +701,8 @@
// 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());
+ } else if
(indexNames.contains(IndexCostInfo.get(i).first.getIndexName())) {
+ // Only skip this index if it's explicitly in the
skip-index hint
EnumerateJoinsRule.setAnnotation(afce,
SkipSecondaryIndexSearchExpressionAnnotation.newInstance(indexNames));
}
diff --git
a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index-selection/hints-skip-index/hints-skip-index-12.sqlpp
b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index-selection/hints-skip-index/hints-skip-index-12.sqlpp
index f494d0e..123167b 100644
---
a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index-selection/hints-skip-index/hints-skip-index-12.sqlpp
+++
b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index-selection/hints-skip-index/hints-skip-index-12.sqlpp
@@ -50,7 +50,6 @@
create index idx_2k on tenk(twothousand);
/*
- * disjunctive predicate is translated into an index join, use skip-index to
disable idx_1k for index join.
* explain plan -> expect index join using idx_1k_2k
*/
diff --git
a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q22.plan
b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q22.plan
new file mode 100644
index 0000000..20ea9cf
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q22.plan
@@ -0,0 +1,132 @@
+distribute result [$$141] [cardinality: 5.0E11, doc-size: -2.0, op-cost: 0.0,
total-cost: 1.000006E12]
+-- DISTRIBUTE_RESULT |PARTITIONED|
+ exchange [cardinality: 5.0E11, doc-size: -2.0, op-cost: 0.0, total-cost:
1.000006E12]
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ assign [$$141] <- [{"country": $#1, "numcust": $$148, "totacctbal":
$$149}] project: [$$141] [cardinality: 5.0E11, doc-size: -2.0, op-cost: 0.0,
total-cost: 1.000006E12]
+ -- ASSIGN |PARTITIONED|
+ exchange [cardinality: 5.0E11, doc-size: -2.0, op-cost: 0.0, total-cost:
1.000006E12]
+ -- SORT_MERGE_EXCHANGE [$#1(ASC) ] |PARTITIONED|
+ group by ([$#1 := $$191]) decor ([]) {
+ aggregate [$$148, $$149] <- [agg-sql-sum($$189),
agg-global-sql-sum($$190)] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0,
total-cost: 0.0]
+ -- AGGREGATE |LOCAL|
+ nested tuple source [cardinality: 0.0, doc-size: 0.0,
op-cost: 0.0, total-cost: 0.0]
+ -- NESTED_TUPLE_SOURCE |LOCAL|
+ } [cardinality: 5.0E11, doc-size: -2.0, op-cost: 0.0,
total-cost: 1.000006E12]
+ -- SORT_GROUP_BY[$$191] |PARTITIONED|
+ exchange [cardinality: 5.0E11, doc-size: -2.0, op-cost: 0.0,
total-cost: 1.000006E12]
+ -- HASH_PARTITION_EXCHANGE [$$191] |PARTITIONED|
+ group by ([$$191 := $$142]) decor ([]) {
+ aggregate [$$189, $$190] <- [agg-sql-count(1),
agg-local-sql-sum($$154)] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0,
total-cost: 0.0]
+ -- AGGREGATE |LOCAL|
+ nested tuple source [cardinality: 0.0, doc-size: 0.0,
op-cost: 0.0, total-cost: 0.0]
+ -- NESTED_TUPLE_SOURCE |LOCAL|
+ } [cardinality: 5.0E11, doc-size: -2.0, op-cost: 0.0,
total-cost: 1.000006E12]
+ -- SORT_GROUP_BY[$$142] |PARTITIONED|
+ exchange [cardinality: 5.0E11, doc-size: -2.0, op-cost: 0.0,
total-cost: 1.000006E12]
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ assign [$$142] <- [substring1($$177, 1, 1)] project: [$$154,
$$142] [cardinality: 5.0E11, doc-size: -2.0, op-cost: 0.0, total-cost:
1.000006E12]
+ -- ASSIGN |PARTITIONED|
+ select (not(neq($$147, 0))) project: [$$177, $$154]
[cardinality: 5.0E11, doc-size: -2.0, op-cost: 0.0, total-cost: 1.000006E12]
+ -- STREAM_SELECT |PARTITIONED|
+ project ([$$147, $$177, $$154]) [cardinality: 5.0E11,
doc-size: -2.0, op-cost: 0.0, total-cost: 1.000006E12]
+ -- STREAM_PROJECT |PARTITIONED|
+ exchange [cardinality: 5.0E11, doc-size: -2.0, op-cost:
0.0, total-cost: 1.000006E12]
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ group by ([$$181 := $$187; $$182 := $$188]) decor
([$$177; $$154]) {
+ aggregate [$$147] <- [agg-sum($$186)]
[cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+ -- AGGREGATE |LOCAL|
+ nested tuple source [cardinality: 0.0,
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+ -- NESTED_TUPLE_SOURCE |LOCAL|
+ } [cardinality: 5.0E11, doc-size: -2.0,
op-cost: 0.0, total-cost: 1.000006E12]
+ -- SORT_GROUP_BY[$$187, $$188] |PARTITIONED|
+ exchange [cardinality: 5.0E11, doc-size: -2.0,
op-cost: 0.0, total-cost: 1.000006E12]
+ -- HASH_PARTITION_EXCHANGE [$$187, $$188]
|PARTITIONED|
+ group by ([$$187 := $$144; $$188 := $$104]) decor
([$$177; $$154]) {
+ aggregate [$$186] <- [agg-count(1)]
[cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+ -- AGGREGATE |LOCAL|
+ select (not(is-missing($$180)))
[cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+ -- STREAM_SELECT |LOCAL|
+ project ([$$180]) [cardinality: 0.0,
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+ -- STREAM_PROJECT |LOCAL|
+ nested tuple source [cardinality:
0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+ -- NESTED_TUPLE_SOURCE |LOCAL|
+ } [cardinality: 5.0E11, doc-size: -2.0,
op-cost: 0.0, total-cost: 1.000006E12]
+ -- PRE_CLUSTERED_GROUP_BY[$$144, $$104]
|PARTITIONED|
+ exchange [cardinality: 5.0E11, doc-size: -2.0,
op-cost: 0.0, total-cost: 1.000006E12]
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ order (ASC, $$144) (ASC, $$104) [cardinality:
5.0E11, doc-size: -2.0, op-cost: 0.0, total-cost: 1.000006E12]
+ -- STABLE_SORT [$$144(ASC), $$104(ASC)]
|PARTITIONED|
+ exchange [cardinality: 5.0E11, doc-size:
-2.0, op-cost: 0.0, total-cost: 1.000006E12]
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ project ([$$154, $$177, $$180, $$144,
$$104]) [cardinality: 5.0E11, doc-size: -2.0, op-cost: 0.0, total-cost:
1.000006E12]
+ -- STREAM_PROJECT |PARTITIONED|
+ exchange [cardinality: 5.0E11, doc-size:
-2.0, op-cost: 0.0, total-cost: 1.000006E12]
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ left outer join (and(eq($$156, $$157),
eq($$158, $$159), eq($$160, $$161))) [cardinality: 6.25E16, doc-size: -3.0,
op-cost: 5.00004E11, total-cost: 1.500015E12]
+ -- HYBRID_HASH_JOIN [$$157, $$159,
$$161][$$156, $$158, $$160] |PARTITIONED|
+ exchange [cardinality: 5.0E11,
doc-size: -2.0, op-cost: 0.0, total-cost: 1.000006E12]
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ project ([$$154, $$177, $$144,
$$104, $$157, $$159, $$161]) [cardinality: 5.0E11, doc-size: -2.0, op-cost:
0.0, total-cost: 1.000006E12]
+ -- STREAM_PROJECT |PARTITIONED|
+ exchange [cardinality: 5.0E11,
doc-size: -2.0, op-cost: 0.0, total-cost: 1.000006E12]
+ -- ONE_TO_ONE_EXCHANGE
|PARTITIONED|
+ join (gt($$154, $$155))
[cardinality: 5.0E11, doc-size: -2.0, op-cost: 1.0E12, total-cost: 1.000006E12]
+ -- NESTED_LOOP |PARTITIONED|
+ exchange [cardinality:
1000000.0, doc-size: -1.0, op-cost: 0.0, total-cost: 1000000.0]
+ -- ONE_TO_ONE_EXCHANGE
|PARTITIONED|
+ select (or(eq($$193, "1"),
eq($$193, "2"), eq($$193, "3"), eq($$193, "4"), eq($$193, "5"), eq($$193, "6"),
eq($$193, "7"))) project: [$$154, $$177, $$144, $$157, $$159, $$161]
[cardinality: 1000000.0, doc-size: -1.0, op-cost: 0.0, total-cost: 1000000.0]
+ -- STREAM_SELECT
|PARTITIONED|
+ assign [$$193, $$177,
$$161, $$159, $$157, $$154] <- [substring1($$c.getField("c_phone"), 1, 1),
$$c.getField("c_state"), $$c.getField("c_w_id"), $$c.getField("c_id"),
$$c.getField("c_d_id"), $$c.getField("c_balance")] project: [$$144, $$193,
$$177, $$161, $$159, $$157, $$154] [cardinality: 1000000.0, doc-size: -1.0,
op-cost: 0.0, total-cost: 1000000.0]
+ -- ASSIGN |PARTITIONED|
+ exchange [cardinality:
1000000.0, doc-size: -1.0, op-cost: 0.0, total-cost: 1000000.0]
+ -- ONE_TO_ONE_EXCHANGE
|PARTITIONED|
+ data-scan
[]<-[$$144, $$c] <- test.customer [cardinality: 1000000.0, doc-size: -1.0,
op-cost: 0.0, total-cost: 1000000.0]
+ -- DATASOURCE_SCAN
|PARTITIONED|
+ exchange
[cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+ --
ONE_TO_ONE_EXCHANGE |PARTITIONED|
+
empty-tuple-source [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost:
0.0]
+ --
EMPTY_TUPLE_SOURCE |PARTITIONED|
+ exchange [cardinality:
1000000.0, doc-size: -1.0, op-cost: 0.0, total-cost: 1000000.0]
+ -- BROADCAST_EXCHANGE
|PARTITIONED|
+ assign [$$155] <-
[get-item($$104, 0)] [cardinality: 1000000.0, doc-size: -1.0, op-cost: 0.0,
total-cost: 1000000.0]
+ -- ASSIGN |UNPARTITIONED|
+ aggregate [$$104] <-
[listify($$185)] [cardinality: 1000000.0, doc-size: -1.0, op-cost: 0.0,
total-cost: 1000000.0]
+ -- AGGREGATE
|UNPARTITIONED|
+ aggregate [$$185] <-
[agg-global-sql-avg($$192)] [cardinality: 1000000.0, doc-size: -1.0, op-cost:
0.0, total-cost: 1000000.0]
+ -- AGGREGATE
|UNPARTITIONED|
+ exchange
[cardinality: 1000000.0, doc-size: -1.0, op-cost: 0.0, total-cost: 1000000.0]
+ --
RANDOM_MERGE_EXCHANGE |PARTITIONED|
+ aggregate [$$192]
<- [agg-local-sql-avg($$176)] [cardinality: 1000000.0, doc-size: -1.0, op-cost:
0.0, total-cost: 1000000.0]
+ -- AGGREGATE
|PARTITIONED|
+ select
(and(or(eq($$194, "1"), eq($$194, "2"), eq($$194, "3"), eq($$194, "4"),
eq($$194, "5"), eq($$194, "6"), eq($$194, "7")), gt($$176, 0.0))) project:
[$$176] [cardinality: 1000000.0, doc-size: -1.0, op-cost: 0.0, total-cost:
1000000.0]
+ -- STREAM_SELECT
|PARTITIONED|
+ assign [$$194,
$$176] <- [substring1($$152.getField("c_phone"), 1, 1),
$$152.getField("c_balance")] project: [$$194, $$176] [cardinality: 1000000.0,
doc-size: -1.0, op-cost: 0.0, total-cost: 1000000.0]
+ -- ASSIGN
|PARTITIONED|
+ project
([$$152]) [cardinality: 1000000.0, doc-size: -1.0, op-cost: 0.0, total-cost:
1000000.0]
+ --
STREAM_PROJECT |PARTITIONED|
+ exchange
[cardinality: 1000000.0, doc-size: -1.0, op-cost: 0.0, total-cost: 1000000.0]
+ --
ONE_TO_ONE_EXCHANGE |PARTITIONED|
+
data-scan []<-[$$153, $$152] <- test.customer [cardinality: 1000000.0,
doc-size: -1.0, op-cost: 0.0, total-cost: 1000000.0]
+ --
DATASOURCE_SCAN |PARTITIONED|
+
exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+ --
ONE_TO_ONE_EXCHANGE |PARTITIONED|
+
empty-tuple-source [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost:
0.0]
+ --
EMPTY_TUPLE_SOURCE |PARTITIONED|
+ exchange [cardinality: 0.0,
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+ -- BROADCAST_EXCHANGE |PARTITIONED|
+ assign [$$180] <- [true]
[cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+ -- ASSIGN |PARTITIONED|
+ select (and(ge($$143,
"2013-12-01 00:00:00"), le($$143, "2013-12-31 00:00:00"))) project: [$$160,
$$158, $$156] [cardinality: 1000000.0, doc-size: -1.0, op-cost: 0.0,
total-cost: 1000000.0]
+ -- STREAM_SELECT |PARTITIONED|
+ assign [$$160, $$158, $$156,
$$143] <- [$$o.getField("o_w_id"), $$o.getField("o_c_id"),
$$o.getField("o_d_id"), $$o.getField("o_entry_d")] project: [$$160, $$158,
$$156, $$143] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+ -- ASSIGN |PARTITIONED|
+ project ([$$o])
[cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+ -- STREAM_PROJECT
|PARTITIONED|
+ exchange [cardinality:
0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+ -- ONE_TO_ONE_EXCHANGE
|PARTITIONED|
+ data-scan []<-[$$146,
$$o] <- test.orders [cardinality: 1000000.0, doc-size: -1.0, op-cost:
1000000.0, total-cost: 1000000.0]
+ -- DATASOURCE_SCAN
|PARTITIONED|
+ exchange [cardinality:
0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+ -- ONE_TO_ONE_EXCHANGE
|PARTITIONED|
+ empty-tuple-source
[cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+ --
EMPTY_TUPLE_SOURCE |PARTITIONED|
diff --git
a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/config/AlgebricksConfig.java
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/config/AlgebricksConfig.java
index b8a37b33..98c9193 100644
---
a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/config/AlgebricksConfig.java
+++
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/config/AlgebricksConfig.java
@@ -38,7 +38,7 @@
public static final boolean CBO_DEFAULT = true;
public static final boolean CBO_TEST_DEFAULT = false;
public static final boolean FORCE_JOIN_ORDER_DEFAULT = false;
- public static final boolean REWRITE_DISJUNCTION_DEFAULT = true;
+ public static final boolean REWRITE_DISJUNCTION_DEFAULT = false;
public static final String QUERY_PLAN_SHAPE_ZIGZAG = "zigzag";
public static final String QUERY_PLAN_SHAPE_LEFTDEEP = "leftdeep";
public static final String QUERY_PLAN_SHAPE_RIGHTDEEP = "rightdeep";
--
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/21080?usp=email
To unsubscribe, or for help writing mail filters, visit
https://asterix-gerrit.ics.uci.edu/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: asterixdb
Gerrit-Branch: phoenix
Gerrit-Change-Id: I0baf0888eb9834fb92f7ce77b8457e76ea0bdee3
Gerrit-Change-Number: 21080
Gerrit-PatchSet: 1
Gerrit-Owner: Shahrzad Shirazi <[email protected]>