This is an automated email from the ASF dual-hosted git repository.

mblow pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/asterixdb.git


The following commit(s) were added to refs/heads/master by this push:
     new bbfd75f948 [ASTERIXDB-3641][COMP] Sampling query taking long time to 
run
bbfd75f948 is described below

commit bbfd75f948e46930d7ea798a7fc0a7e456d008c8
Author: murali4104 <[email protected]>
AuthorDate: Fri Oct 10 11:16:02 2025 -0700

    [ASTERIXDB-3641][COMP] Sampling query taking long time to run
    
    Change-Id: I74d4275581923a297b40126a2f8ffb68d13b2917
    Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/20408
    Integration-Tests: Jenkins <[email protected]>
    Tested-by: Jenkins <[email protected]>
    Reviewed-by: Preetham Poluparthi <[email protected]>
---
 .../apache/asterix/optimizer/rules/cbo/Stats.java  |  66 ++++++++++--
 .../join-queries/join-queries.8.plan               |  30 +++---
 .../other-pushdowns/other-pushdowns.015.plan       |  18 ++--
 .../hash-join-with-redundant-variable.04.plan      |  18 ++--
 .../hash-join-with-redundant-variable.06.plan      |  18 ++--
 .../hash-join-with-redundant-variable.08.plan      |  12 +--
 .../hash-join-with-redundant-variable.10.plan      |  18 ++--
 .../hash-join-with-redundant-variable.12.plan      |  14 +--
 .../hash-join-with-redundant-variable.14.plan      |  18 ++--
 .../hash-join-with-redundant-variable.16.plan      |  18 ++--
 .../index-only-leftouterjoin.007.plan              |  14 +--
 .../index-only-leftouterjoin.008.plan              |  14 +--
 .../index-only-leftouterjoin.009.plan              |  14 +--
 .../index-only-leftouterjoin.010.plan              |  16 +--
 .../push-limit-to-primary-scan-select.5.plan       |  18 ++--
 .../tpch/query-plans/query-plans.10.plan           | 112 ++++++++++-----------
 16 files changed, 233 insertions(+), 185 deletions(-)

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 aa73da13e0..72ec179e93 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
@@ -19,6 +19,8 @@
 
 package org.apache.asterix.optimizer.rules.cbo;
 
+import static 
org.apache.asterix.om.functions.BuiltinFunctions.getBuiltinFunctionInfo;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -172,17 +174,44 @@ public class Stats {
                 return 0.5;
             }
 
-            boolean unnestOp1 = 
joinEnum.findUnnestOp(joinEnum.leafInputs.get(idx1 - 1));
-            boolean unnestOp2 = 
joinEnum.findUnnestOp(joinEnum.leafInputs.get(idx2 - 1));
-            boolean unnestOp = unnestOp1 || unnestOp2;
-            boolean okOp = acceptableOp(joinExpr.getFunctionIdentifier());
             ILogicalOperator leafInput1 = joinEnum.leafInputs.get(idx1 - 1);
             ILogicalOperator leafInput2 = joinEnum.leafInputs.get(idx2 - 1);
+            boolean unnestOp1 = joinEnum.findUnnestOp(leafInput1);
+            boolean unnestOp2 = joinEnum.findUnnestOp(leafInput2);
+            boolean unnestOp = unnestOp1 || unnestOp2;
+
             LogicalVariable var1 = exprUsedVars.get(0);
             LogicalVariable var2 = exprUsedVars.get(1);
+            // find if this join part of a composite join R.a = S.a and R.b = 
S.b and ...
+            List<Integer> compositeJoins = new ArrayList<>();
+            for (int i = 0; i < joinEnum.joinConditions.size(); i++) {
+                if (joinEnum.joinConditions.get(i).datasetBits == 
jc.datasetBits) {
+                    compositeJoins.add(i);
+                }
+            }
+            int size = compositeJoins.size();
+            if (size > 1) { // for composite joins, we will always resort to 
joining with samples
+                joinExpr = combineJoinExprs(compositeJoins);
+                double sels = 
findJoinSelFromSamples(joinEnum.leafInputs.get(idx1 - 1),
+                        joinEnum.leafInputs.get(idx2 - 1), index1, index2, 
joinExpr, jOp);
+                if (sels == 0.0) {
+                    sels = 1.0 / Math.max(card1, card2);
+                }
+                for (int i = 0; i < compositeJoins.size(); i++) {
+                    
joinEnum.joinConditions.get(compositeJoins.get(i)).selectivity = sels;
+                    // Later on we will make the selectivity of just one of 
these to be sels and the others
+                    // will have a selectivity of 1.0.
+                }
+                return sels;
+            }
+
+            boolean okOp = acceptableOp(joinExpr.getFunctionIdentifier());
             // If there are more than 2 variables, it is not a simple join 
like r.a op s.a
-            if (okOp && !unnestOp && (exprUsedVars.size() > 2
-                    || isJoinSelFromSamplesApplicable(leafInput1, leafInput2, 
index1, index2, var1, var2))) {
+            Index.SampleIndexDetails idxDetails1 = (Index.SampleIndexDetails) 
index1.getIndexDetails();
+            Index.SampleIndexDetails idxDetails2 = (Index.SampleIndexDetails) 
index2.getIndexDetails();
+            if (((idxDetails1.getSourceCardinality() < 
idxDetails1.getSampleCardinalityTarget())
+                    || (idxDetails2.getSourceCardinality() < 
idxDetails2.getSampleCardinalityTarget())
+                    || exprUsedVars.size() > 2) && !unnestOp && okOp) {
                 double sels = 
findJoinSelFromSamples(joinEnum.leafInputs.get(idx1 - 1),
                         joinEnum.leafInputs.get(idx2 - 1), index1, index2, 
joinExpr, jOp);
                 if (sels == 0.0) {
@@ -190,10 +219,23 @@ public class Stats {
                 }
                 return sels;
             }
-            // Now we can handle only equi joins. We make all the uniform and 
independence assumptions here.
+            //At this point, a single join will be treated as an EQ join even 
if it is not. Not ideal but no other choice
+            // for example interval-overlap falls into this case. For some 
reason, joining samples with interval-overlap fails,
+            // so defaulting to this case.
             double seln = naiveJoinSelectivity(exprUsedVars, card1, card2, 
idx1, idx2, unnestOp1, unnestOp2);
             return seln;
         }
+
+    }
+
+    private AbstractFunctionCallExpression combineJoinExprs(List<Integer> 
compositeJoins) {
+        ScalarFunctionCallExpression andExpr = new 
ScalarFunctionCallExpression(
+                
BuiltinFunctions.getBuiltinFunctionInfo(AlgebricksBuiltinFunctions.AND));
+        for (int i = 0; i < compositeJoins.size(); i++) {
+            JoinCondition jc = 
joinEnum.joinConditions.get(compositeJoins.get(i));
+            andExpr.getArguments().add(new MutableObject<>(jc.joinCondition));
+        }
+        return andExpr;
     }
 
     private boolean isJoinSelFromSamplesApplicable(ILogicalOperator 
leafInput1, ILogicalOperator leafInput2,
@@ -235,10 +277,14 @@ public class Stats {
         return numDistincts;
     }
 
+    //Goal is to keep expanding the list of ops here.
     private boolean acceptableOp(FunctionIdentifier functionIdentifier) {
         if (functionIdentifier.equals(AlgebricksBuiltinFunctions.NEQ)) {
             return true;
         }
+        if (functionIdentifier.equals(AlgebricksBuiltinFunctions.EQ)) {
+            return true;
+        }
         if (functionIdentifier.equals(AlgebricksBuiltinFunctions.LT)) {
             return true;
         }
@@ -423,8 +469,10 @@ public class Stats {
             }
         } else {
             JoinProductivityAnnotation jpa = 
afcExpr.getAnnotation(JoinProductivityAnnotation.class);
-            s = findJoinSelectivity(jc, jpa, afcExpr, jOp);
-            sel *= s;
+            if (jc.selectivity == -1.0) {
+                s = findJoinSelectivity(jc, jpa, afcExpr, jOp);
+                sel *= s;
+            }
         }
 
         List<LogicalVariable> usedVars = new ArrayList<>();
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/cardinality-estimation/join-queries/join-queries.8.plan
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/cardinality-estimation/join-queries/join-queries.8.plan
index 4fd759bac6..3eb913a973 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/cardinality-estimation/join-queries/join-queries.8.plan
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/cardinality-estimation/join-queries/join-queries.8.plan
@@ -1,42 +1,42 @@
-distribute result [$$119] [cardinality: 24.0, doc-size: 45.0, op-cost: 0.0, 
total-cost: 7030.27]
+distribute result [$$119] [cardinality: 24.0, doc-size: 45.0, op-cost: 0.0, 
total-cost: 6741.88]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 24.0, doc-size: 45.0, op-cost: 0.0, total-cost: 
7030.27]
+  exchange [cardinality: 24.0, doc-size: 45.0, op-cost: 0.0, total-cost: 
6741.88]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$119] <- [{"n_name": $$n_name, "revenue": $$132}] project: 
[$$119] [cardinality: 24.0, doc-size: 45.0, op-cost: 0.0, total-cost: 7030.27]
+    assign [$$119] <- [{"n_name": $$n_name, "revenue": $$132}] project: 
[$$119] [cardinality: 24.0, doc-size: 45.0, op-cost: 0.0, total-cost: 6741.88]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 24.0, doc-size: 45.0, op-cost: 0.0, total-cost: 
7030.27]
+      exchange [cardinality: 24.0, doc-size: 45.0, op-cost: 0.0, total-cost: 
6741.88]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
         group by ([$$n_name := $$142]) decor ([]) {
                   aggregate [$$132] <- [global-sql-sum-serial($$141)] 
[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: 24.0, doc-size: 45.0, op-cost: 0.0, total-cost: 
7030.27]
+               } [cardinality: 24.0, doc-size: 45.0, op-cost: 0.0, total-cost: 
6741.88]
         -- EXTERNAL_GROUP_BY[$$142]  |PARTITIONED|
-          exchange [cardinality: 24.0, doc-size: 45.0, op-cost: 0.0, 
total-cost: 6919.69]
+          exchange [cardinality: 24.0, doc-size: 45.0, op-cost: 0.0, 
total-cost: 6703.4]
           -- HASH_PARTITION_EXCHANGE [$$142]  |PARTITIONED|
             group by ([$$142 := $$120]) decor ([]) {
                       aggregate [$$141] <- 
[local-sql-sum-serial(numeric-multiply($$139, numeric-subtract(1, $$140)))] 
[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: 24.0, doc-size: 45.0, op-cost: 0.0, 
total-cost: 6919.69]
+                   } [cardinality: 24.0, doc-size: 45.0, op-cost: 0.0, 
total-cost: 6703.4]
             -- EXTERNAL_GROUP_BY[$$120]  |PARTITIONED|
-              exchange [cardinality: 110.58, doc-size: 45.0, op-cost: 0.0, 
total-cost: 6809.11]
+              exchange [cardinality: 38.48, doc-size: 45.0, op-cost: 0.0, 
total-cost: 6664.92]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                project ([$$139, $$140, $$120]) [cardinality: 110.58, 
doc-size: 45.0, op-cost: 0.0, total-cost: 6809.11]
+                project ([$$139, $$140, $$120]) [cardinality: 38.48, doc-size: 
45.0, op-cost: 0.0, total-cost: 6664.92]
                 -- STREAM_PROJECT  |PARTITIONED|
-                  exchange [cardinality: 110.58, doc-size: 45.0, op-cost: 0.0, 
total-cost: 6809.11]
+                  exchange [cardinality: 38.48, doc-size: 45.0, op-cost: 0.0, 
total-cost: 6664.92]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    join (eq($$130, $$128)) [cardinality: 110.58, doc-size: 
45.0, op-cost: 135.58, total-cost: 6809.11]
+                    join (eq($$130, $$128)) [cardinality: 38.48, doc-size: 
45.0, op-cost: 63.48, total-cost: 6664.92]
                     -- HYBRID_HASH_JOIN [$$130][$$128]  |PARTITIONED|
-                      exchange [cardinality: 110.58, doc-size: 40.0, op-cost: 
0.0, total-cost: 6512.96]
+                      exchange [cardinality: 38.48, doc-size: 40.0, op-cost: 
0.0, total-cost: 6512.96]
                       -- HASH_PARTITION_EXCHANGE [$$130]  |PARTITIONED|
-                        project ([$$139, $$140, $$130]) [cardinality: 110.58, 
doc-size: 40.0, op-cost: 0.0, total-cost: 6512.96]
+                        project ([$$139, $$140, $$130]) [cardinality: 38.48, 
doc-size: 40.0, op-cost: 0.0, total-cost: 6512.96]
                         -- STREAM_PROJECT  |PARTITIONED|
-                          exchange [cardinality: 110.58, doc-size: 40.0, 
op-cost: 0.0, total-cost: 6512.96]
+                          exchange [cardinality: 38.48, doc-size: 40.0, 
op-cost: 0.0, total-cost: 6512.96]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            join (and(eq($$133, $$127), eq($$130, $$131))) 
[cardinality: 110.58, doc-size: 40.0, op-cost: 1035.18, total-cost: 6512.96]
+                            join (and(eq($$133, $$127), eq($$130, $$131))) 
[cardinality: 38.48, doc-size: 40.0, op-cost: 1035.18, total-cost: 6512.96]
                             -- HYBRID_HASH_JOIN [$$133, $$131][$$127, $$130]  
|PARTITIONED|
                               exchange [cardinality: 6010.65, doc-size: 10.0, 
op-cost: 0.0, total-cost: 6005.0]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.015.plan
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.015.plan
index 8aae0e397d..29e8edcc12 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.015.plan
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.015.plan
@@ -1,20 +1,20 @@
-distribute result [$$52] [cardinality: 4.0, doc-size: 2.0, op-cost: 0.0, 
total-cost: 12.0]
+distribute result [$$52] [cardinality: 2.1, doc-size: 2.0, op-cost: 0.0, 
total-cost: 12.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
-  exchange [cardinality: 4.0, doc-size: 2.0, op-cost: 0.0, total-cost: 12.0]
+  exchange [cardinality: 2.1, doc-size: 2.0, op-cost: 0.0, total-cost: 12.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
-    assign [$$52] <- [{"$1": $$57}] project: [$$52] [cardinality: 4.0, 
doc-size: 2.0, op-cost: 0.0, total-cost: 12.0]
+    assign [$$52] <- [{"$1": $$57}] project: [$$52] [cardinality: 2.1, 
doc-size: 2.0, op-cost: 0.0, total-cost: 12.0]
     -- ASSIGN  |UNPARTITIONED|
-      aggregate [$$57] <- [agg-sql-sum($$60)] [cardinality: 4.0, doc-size: 
2.0, op-cost: 0.0, total-cost: 12.0]
+      aggregate [$$57] <- [agg-sql-sum($$60)] [cardinality: 2.1, doc-size: 
2.0, op-cost: 0.0, total-cost: 12.0]
       -- AGGREGATE  |UNPARTITIONED|
-        exchange [cardinality: 4.0, doc-size: 2.0, op-cost: 0.0, total-cost: 
12.0]
+        exchange [cardinality: 2.1, doc-size: 2.0, op-cost: 0.0, total-cost: 
12.0]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
-          aggregate [$$60] <- [agg-sql-count($$50)] [cardinality: 4.0, 
doc-size: 2.0, op-cost: 0.0, total-cost: 12.0]
+          aggregate [$$60] <- [agg-sql-count($$50)] [cardinality: 2.1, 
doc-size: 2.0, op-cost: 0.0, total-cost: 12.0]
           -- AGGREGATE  |PARTITIONED|
-            project ([$$50]) [cardinality: 4.0, doc-size: 2.0, op-cost: 0.0, 
total-cost: 12.0]
+            project ([$$50]) [cardinality: 2.1, doc-size: 2.0, op-cost: 0.0, 
total-cost: 12.0]
             -- STREAM_PROJECT  |PARTITIONED|
-              exchange [cardinality: 4.0, doc-size: 2.0, op-cost: 0.0, 
total-cost: 12.0]
+              exchange [cardinality: 2.1, doc-size: 2.0, op-cost: 0.0, 
total-cost: 12.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                join (eq($$55, $$56)) [cardinality: 4.0, doc-size: 2.0, 
op-cost: 4.0, total-cost: 12.0]
+                join (eq($$55, $$56)) [cardinality: 2.1, doc-size: 2.0, 
op-cost: 4.0, total-cost: 12.0]
                 -- HYBRID_HASH_JOIN [$$55][$$56]  |PARTITIONED|
                   exchange [cardinality: 2.0, doc-size: 1.0, op-cost: 0.0, 
total-cost: 2.0]
                   -- HASH_PARTITION_EXCHANGE [$$55]  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.04.plan
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.04.plan
index 5d4a8329ff..c7bc448478 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.04.plan
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.04.plan
@@ -1,20 +1,20 @@
-distribute result [$$51] [cardinality: 166.67, doc-size: 15.0, op-cost: 0.0, 
total-cost: 1710.17]
+distribute result [$$51] [cardinality: 58.0, doc-size: 15.0, op-cost: 0.0, 
total-cost: 819.76]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 166.67, doc-size: 15.0, op-cost: 0.0, total-cost: 
1710.17]
+  exchange [cardinality: 58.0, doc-size: 15.0, op-cost: 0.0, total-cost: 
819.76]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$51] <- [{"n_nationkey": $$58, "s_nationkey": $$56, 
"c_nationkey": $$55}] project: [$$51] [cardinality: 166.67, doc-size: 15.0, 
op-cost: 0.0, total-cost: 1710.17]
+    assign [$$51] <- [{"n_nationkey": $$58, "s_nationkey": $$56, 
"c_nationkey": $$55}] project: [$$51] [cardinality: 58.0, doc-size: 15.0, 
op-cost: 0.0, total-cost: 819.76]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 166.67, doc-size: 15.0, op-cost: 0.0, total-cost: 
1710.17]
+      exchange [cardinality: 58.0, doc-size: 15.0, op-cost: 0.0, total-cost: 
819.76]
       -- SORT_MERGE_EXCHANGE [$$58(ASC), $$56(ASC), $$55(ASC) ]  |PARTITIONED|
-        order (ASC, $$58) (ASC, $$56) (ASC, $$55) [cardinality: 166.67, 
doc-size: 15.0, op-cost: 0.0, total-cost: 1710.17]
+        order (ASC, $$58) (ASC, $$56) (ASC, $$55) [cardinality: 58.0, 
doc-size: 15.0, op-cost: 0.0, total-cost: 819.76]
         -- STABLE_SORT [$$58(ASC), $$56(ASC), $$55(ASC)]  |PARTITIONED|
-          exchange [cardinality: 166.67, doc-size: 15.0, op-cost: 0.0, 
total-cost: 480.0]
+          exchange [cardinality: 58.0, doc-size: 15.0, op-cost: 0.0, 
total-cost: 480.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            project ([$$58, $$56, $$55]) [cardinality: 166.67, doc-size: 15.0, 
op-cost: 0.0, total-cost: 480.0]
+            project ([$$58, $$56, $$55]) [cardinality: 58.0, doc-size: 15.0, 
op-cost: 0.0, total-cost: 480.0]
             -- STREAM_PROJECT  |PARTITIONED|
-              exchange [cardinality: 166.67, doc-size: 15.0, op-cost: 0.0, 
total-cost: 480.0]
+              exchange [cardinality: 58.0, doc-size: 15.0, op-cost: 0.0, 
total-cost: 480.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                join (and(eq($$55, $$58), eq($$56, $$66))) [cardinality: 
166.67, doc-size: 15.0, op-cost: 190.0, total-cost: 480.0]
+                join (and(eq($$55, $$58), eq($$56, $$66))) [cardinality: 58.0, 
doc-size: 15.0, op-cost: 190.0, total-cost: 480.0]
                 -- HYBRID_HASH_JOIN [$$55, $$66][$$58, $$56]  |PARTITIONED|
                   exchange [cardinality: 150.0, doc-size: 5.0, op-cost: 0.0, 
total-cost: 150.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.06.plan
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.06.plan
index fdad6dd95e..9a4d2e17e9 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.06.plan
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.06.plan
@@ -1,20 +1,20 @@
-distribute result [$$36] [cardinality: 4.01, doc-size: 15.0, op-cost: 0.0, 
total-cost: 22537.15]
+distribute result [$$36] [cardinality: 7.99, doc-size: 15.0, op-cost: 0.0, 
total-cost: 22553.08]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 4.01, doc-size: 15.0, op-cost: 0.0, total-cost: 
22537.15]
+  exchange [cardinality: 7.99, doc-size: 15.0, op-cost: 0.0, total-cost: 
22553.08]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$36] <- [{"o_orderkey": $$43, "l_orderkey": $$44, "l_suppkey": 
$$42}] project: [$$36] [cardinality: 4.01, doc-size: 15.0, op-cost: 0.0, 
total-cost: 22537.15]
+    assign [$$36] <- [{"o_orderkey": $$43, "l_orderkey": $$44, "l_suppkey": 
$$42}] project: [$$36] [cardinality: 7.99, doc-size: 15.0, op-cost: 0.0, 
total-cost: 22553.08]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 4.01, doc-size: 15.0, op-cost: 0.0, total-cost: 
22537.15]
+      exchange [cardinality: 7.99, doc-size: 15.0, op-cost: 0.0, total-cost: 
22553.08]
       -- SORT_MERGE_EXCHANGE [$$43(ASC), $$44(ASC), $$42(ASC) ]  |PARTITIONED|
-        order (ASC, $$43) (ASC, $$44) (ASC, $$42) [cardinality: 4.01, 
doc-size: 15.0, op-cost: 0.0, total-cost: 22537.15]
+        order (ASC, $$43) (ASC, $$44) (ASC, $$42) [cardinality: 7.99, 
doc-size: 15.0, op-cost: 0.0, total-cost: 22553.08]
         -- STABLE_SORT [$$43(ASC), $$44(ASC), $$42(ASC)]  |PARTITIONED|
-          exchange [cardinality: 4.01, doc-size: 15.0, op-cost: 0.0, 
total-cost: 22529.12]
+          exchange [cardinality: 7.99, doc-size: 15.0, op-cost: 0.0, 
total-cost: 22529.12]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            project ([$$43, $$44, $$42]) [cardinality: 4.01, doc-size: 15.0, 
op-cost: 0.0, total-cost: 22529.12]
+            project ([$$43, $$44, $$42]) [cardinality: 7.99, doc-size: 15.0, 
op-cost: 0.0, total-cost: 22529.12]
             -- STREAM_PROJECT  |PARTITIONED|
-              exchange [cardinality: 4.01, doc-size: 15.0, op-cost: 0.0, 
total-cost: 22529.12]
+              exchange [cardinality: 7.99, doc-size: 15.0, op-cost: 0.0, 
total-cost: 22529.12]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                join (and(eq($$43, $$44), eq($$49, $$42))) [cardinality: 4.01, 
doc-size: 15.0, op-cost: 7512.06, total-cost: 22529.12]
+                join (and(eq($$43, $$44), eq($$49, $$42))) [cardinality: 7.99, 
doc-size: 15.0, op-cost: 7512.06, total-cost: 22529.12]
                 -- HYBRID_HASH_JOIN [$$44, $$42][$$43, $$49]  |PARTITIONED|
                   exchange [cardinality: 6005.0, doc-size: 10.0, op-cost: 0.0, 
total-cost: 6005.0]
                   -- HASH_PARTITION_EXCHANGE [$$44]  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.08.plan
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.08.plan
index a5cddf04c5..6494419323 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.08.plan
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.08.plan
@@ -1,12 +1,12 @@
-distribute result [$$38] [cardinality: 1500.0, doc-size: 5.0, op-cost: 0.0, 
total-cost: 1508.03]
+distribute result [$$38] [cardinality: 1500.0, doc-size: 5.0, op-cost: 0.0, 
total-cost: 1519.95]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 1500.0, doc-size: 5.0, op-cost: 0.0, total-cost: 
1508.03]
+  exchange [cardinality: 1500.0, doc-size: 5.0, op-cost: 0.0, total-cost: 
1519.95]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$38] <- [{"o_orderkey": $$43, "l_orderkey": $$44, "l_suppkey": 
$$47}] project: [$$38] [cardinality: 1500.0, doc-size: 5.0, op-cost: 0.0, 
total-cost: 1508.03]
+    assign [$$38] <- [{"o_orderkey": $$43, "l_orderkey": $$44, "l_suppkey": 
$$47}] project: [$$38] [cardinality: 1500.0, doc-size: 5.0, op-cost: 0.0, 
total-cost: 1519.95]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 1500.0, doc-size: 5.0, op-cost: 0.0, total-cost: 
1508.03]
+      exchange [cardinality: 1500.0, doc-size: 5.0, op-cost: 0.0, total-cost: 
1519.95]
       -- SORT_MERGE_EXCHANGE [$$43(ASC), $$44(ASC), $$47(ASC) ]  |PARTITIONED|
-        order (ASC, $$43) (ASC, $$44) (ASC, $$47) [cardinality: 1500.0, 
doc-size: 5.0, op-cost: 0.0, total-cost: 1508.03]
+        order (ASC, $$43) (ASC, $$44) (ASC, $$47) [cardinality: 1500.0, 
doc-size: 5.0, op-cost: 0.0, total-cost: 1519.95]
         -- STABLE_SORT [$$43(ASC), $$44(ASC), $$47(ASC)]  |PARTITIONED|
           exchange [cardinality: 1500.0, doc-size: 5.0, op-cost: 0.0, 
total-cost: 1500.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
@@ -14,7 +14,7 @@ distribute result [$$38] [cardinality: 1500.0, doc-size: 5.0, 
op-cost: 0.0, tota
             -- STREAM_PROJECT  |PARTITIONED|
               exchange [cardinality: 1500.0, doc-size: 5.0, op-cost: 0.0, 
total-cost: 1500.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                left outer join (and(eq($$43, $$44), eq($$56, $$47))) 
[cardinality: 4.01, doc-size: 15.0, op-cost: 7512.06, total-cost: 22529.12]
+                left outer join (and(eq($$43, $$44), eq($$56, $$47))) 
[cardinality: 7.07, doc-size: 15.0, op-cost: 7512.06, total-cost: 22529.12]
                 -- HYBRID_HASH_JOIN [$$43, $$56][$$44, $$47]  |PARTITIONED|
                   exchange [cardinality: 1500.0, doc-size: 5.0, op-cost: 0.0, 
total-cost: 1500.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.10.plan
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.10.plan
index 7b44ce5de7..a12dde6e34 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.10.plan
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.10.plan
@@ -1,20 +1,20 @@
-distribute result [$$51] [cardinality: 166.67, doc-size: 15.0, op-cost: 0.0, 
total-cost: 1680.17]
+distribute result [$$51] [cardinality: 58.0, doc-size: 15.0, op-cost: 0.0, 
total-cost: 789.76]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 166.67, doc-size: 15.0, op-cost: 0.0, total-cost: 
1680.17]
+  exchange [cardinality: 58.0, doc-size: 15.0, op-cost: 0.0, total-cost: 
789.76]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$51] <- [{"n_nationkey": $$58, "s_nationkey": $$56, 
"c_nationkey": $$55}] project: [$$51] [cardinality: 166.67, doc-size: 15.0, 
op-cost: 0.0, total-cost: 1680.17]
+    assign [$$51] <- [{"n_nationkey": $$58, "s_nationkey": $$56, 
"c_nationkey": $$55}] project: [$$51] [cardinality: 58.0, doc-size: 15.0, 
op-cost: 0.0, total-cost: 789.76]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 166.67, doc-size: 15.0, op-cost: 0.0, total-cost: 
1680.17]
+      exchange [cardinality: 58.0, doc-size: 15.0, op-cost: 0.0, total-cost: 
789.76]
       -- SORT_MERGE_EXCHANGE [$$58(ASC), $$56(ASC), $$55(ASC) ]  |PARTITIONED|
-        order (ASC, $$58) (ASC, $$56) (ASC, $$55) [cardinality: 166.67, 
doc-size: 15.0, op-cost: 0.0, total-cost: 1680.17]
+        order (ASC, $$58) (ASC, $$56) (ASC, $$55) [cardinality: 58.0, 
doc-size: 15.0, op-cost: 0.0, total-cost: 789.76]
         -- STABLE_SORT [$$58(ASC), $$56(ASC), $$55(ASC)]  |PARTITIONED|
-          exchange [cardinality: 166.67, doc-size: 15.0, op-cost: 0.0, 
total-cost: 450.0]
+          exchange [cardinality: 58.0, doc-size: 15.0, op-cost: 0.0, 
total-cost: 450.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            project ([$$58, $$56, $$55]) [cardinality: 166.67, doc-size: 15.0, 
op-cost: 0.0, total-cost: 450.0]
+            project ([$$58, $$56, $$55]) [cardinality: 58.0, doc-size: 15.0, 
op-cost: 0.0, total-cost: 450.0]
             -- STREAM_PROJECT  |PARTITIONED|
-              exchange [cardinality: 166.67, doc-size: 15.0, op-cost: 0.0, 
total-cost: 450.0]
+              exchange [cardinality: 58.0, doc-size: 15.0, op-cost: 0.0, 
total-cost: 450.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                join (and(eq($$55, $$58), eq($$56, $$66))) [cardinality: 
166.67, doc-size: 15.0, op-cost: 180.0, total-cost: 450.0]
+                join (and(eq($$55, $$58), eq($$56, $$66))) [cardinality: 58.0, 
doc-size: 15.0, op-cost: 180.0, total-cost: 450.0]
                 -- HYBRID_HASH_JOIN [$$55, $$66][$$58, $$56]  |PARTITIONED|
                   exchange [cardinality: 150.0, doc-size: 5.0, op-cost: 0.0, 
total-cost: 150.0]
                   -- RANDOM_PARTITION_EXCHANGE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.12.plan
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.12.plan
index 8fc259cec9..f440f133b7 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.12.plan
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.12.plan
@@ -1,16 +1,16 @@
-distribute result [$$51] [cardinality: 166.67, doc-size: 15.0, op-cost: 0.0, 
total-cost: 1805.17]
+distribute result [$$51] [cardinality: 58.0, doc-size: 15.0, op-cost: 0.0, 
total-cost: 914.76]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 166.67, doc-size: 15.0, op-cost: 0.0, total-cost: 
1805.17]
+  exchange [cardinality: 58.0, doc-size: 15.0, op-cost: 0.0, total-cost: 
914.76]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$51] <- [{"n_nationkey": $$58, "s_nationkey": $$56, 
"c_nationkey": $$55}] project: [$$51] [cardinality: 166.67, doc-size: 15.0, 
op-cost: 0.0, total-cost: 1805.17]
+    assign [$$51] <- [{"n_nationkey": $$58, "s_nationkey": $$56, 
"c_nationkey": $$55}] project: [$$51] [cardinality: 58.0, doc-size: 15.0, 
op-cost: 0.0, total-cost: 914.76]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 166.67, doc-size: 15.0, op-cost: 0.0, total-cost: 
1805.17]
+      exchange [cardinality: 58.0, doc-size: 15.0, op-cost: 0.0, total-cost: 
914.76]
       -- SORT_MERGE_EXCHANGE [$$58(ASC), $$56(ASC), $$55(ASC) ]  |PARTITIONED|
-        order (ASC, $$58) (ASC, $$56) (ASC, $$55) [cardinality: 166.67, 
doc-size: 15.0, op-cost: 0.0, total-cost: 1805.17]
+        order (ASC, $$58) (ASC, $$56) (ASC, $$55) [cardinality: 58.0, 
doc-size: 15.0, op-cost: 0.0, total-cost: 914.76]
         -- STABLE_SORT [$$58(ASC), $$56(ASC), $$55(ASC)]  |PARTITIONED|
-          exchange [cardinality: 166.67, doc-size: 15.0, op-cost: 0.0, 
total-cost: 575.0]
+          exchange [cardinality: 58.0, doc-size: 15.0, op-cost: 0.0, 
total-cost: 575.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            join (eq($$55, $$58)) [cardinality: 166.67, doc-size: 15.0, 
op-cost: 160.0, total-cost: 575.0]
+            join (eq($$55, $$58)) [cardinality: 58.0, doc-size: 15.0, op-cost: 
160.0, total-cost: 575.0]
             -- HYBRID_HASH_JOIN [$$58][$$55]  |PARTITIONED|
               exchange [cardinality: 10.0, doc-size: 10.0, op-cost: 0.0, 
total-cost: 105.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.14.plan
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.14.plan
index df5db0268b..681adee494 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.14.plan
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.14.plan
@@ -1,20 +1,20 @@
-distribute result [$$51] [cardinality: 166.67, doc-size: 15.0, op-cost: 0.0, 
total-cost: 1710.17]
+distribute result [$$51] [cardinality: 58.0, doc-size: 15.0, op-cost: 0.0, 
total-cost: 819.76]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 166.67, doc-size: 15.0, op-cost: 0.0, total-cost: 
1710.17]
+  exchange [cardinality: 58.0, doc-size: 15.0, op-cost: 0.0, total-cost: 
819.76]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$51] <- [{"n_nationkey": $$59, "s_nationkey": $$56, 
"c_nationkey": $$55}] project: [$$51] [cardinality: 166.67, doc-size: 15.0, 
op-cost: 0.0, total-cost: 1710.17]
+    assign [$$51] <- [{"n_nationkey": $$59, "s_nationkey": $$56, 
"c_nationkey": $$55}] project: [$$51] [cardinality: 58.0, doc-size: 15.0, 
op-cost: 0.0, total-cost: 819.76]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 166.67, doc-size: 15.0, op-cost: 0.0, total-cost: 
1710.17]
+      exchange [cardinality: 58.0, doc-size: 15.0, op-cost: 0.0, total-cost: 
819.76]
       -- SORT_MERGE_EXCHANGE [$$59(ASC), $$56(ASC), $$55(ASC) ]  |PARTITIONED|
-        order (ASC, $$59) (ASC, $$56) (ASC, $$55) [cardinality: 166.67, 
doc-size: 15.0, op-cost: 0.0, total-cost: 1710.17]
+        order (ASC, $$59) (ASC, $$56) (ASC, $$55) [cardinality: 58.0, 
doc-size: 15.0, op-cost: 0.0, total-cost: 819.76]
         -- STABLE_SORT [$$59(ASC), $$56(ASC), $$55(ASC)]  |PARTITIONED|
-          exchange [cardinality: 166.67, doc-size: 15.0, op-cost: 0.0, 
total-cost: 480.0]
+          exchange [cardinality: 58.0, doc-size: 15.0, op-cost: 0.0, 
total-cost: 480.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            project ([$$59, $$56, $$55]) [cardinality: 166.67, doc-size: 15.0, 
op-cost: 0.0, total-cost: 480.0]
+            project ([$$59, $$56, $$55]) [cardinality: 58.0, doc-size: 15.0, 
op-cost: 0.0, total-cost: 480.0]
             -- STREAM_PROJECT  |PARTITIONED|
-              exchange [cardinality: 166.67, doc-size: 15.0, op-cost: 0.0, 
total-cost: 480.0]
+              exchange [cardinality: 58.0, doc-size: 15.0, op-cost: 0.0, 
total-cost: 480.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                join (and(eq($$55, $$59), eq($$56, $$66))) [cardinality: 
166.67, doc-size: 15.0, op-cost: 190.0, total-cost: 480.0]
+                join (and(eq($$55, $$59), eq($$56, $$66))) [cardinality: 58.0, 
doc-size: 15.0, op-cost: 190.0, total-cost: 480.0]
                 -- HYBRID_HASH_JOIN [$$55, $$66][$$59, $$56]  |PARTITIONED|
                   exchange [cardinality: 150.0, doc-size: 5.0, op-cost: 0.0, 
total-cost: 150.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.16.plan
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.16.plan
index 6a2aa6ec8d..f731a7f27e 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.16.plan
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.16.plan
@@ -1,20 +1,20 @@
-distribute result [$$51] [cardinality: 166.67, doc-size: 15.0, op-cost: 0.0, 
total-cost: 1680.17]
+distribute result [$$51] [cardinality: 58.0, doc-size: 15.0, op-cost: 0.0, 
total-cost: 789.76]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 166.67, doc-size: 15.0, op-cost: 0.0, total-cost: 
1680.17]
+  exchange [cardinality: 58.0, doc-size: 15.0, op-cost: 0.0, total-cost: 
789.76]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$51] <- [{"n_nationkey": $$59, "s_nationkey": $$56, 
"c_nationkey": $$55}] project: [$$51] [cardinality: 166.67, doc-size: 15.0, 
op-cost: 0.0, total-cost: 1680.17]
+    assign [$$51] <- [{"n_nationkey": $$59, "s_nationkey": $$56, 
"c_nationkey": $$55}] project: [$$51] [cardinality: 58.0, doc-size: 15.0, 
op-cost: 0.0, total-cost: 789.76]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 166.67, doc-size: 15.0, op-cost: 0.0, total-cost: 
1680.17]
+      exchange [cardinality: 58.0, doc-size: 15.0, op-cost: 0.0, total-cost: 
789.76]
       -- SORT_MERGE_EXCHANGE [$$59(ASC), $$56(ASC), $$55(ASC) ]  |PARTITIONED|
-        order (ASC, $$59) (ASC, $$56) (ASC, $$55) [cardinality: 166.67, 
doc-size: 15.0, op-cost: 0.0, total-cost: 1680.17]
+        order (ASC, $$59) (ASC, $$56) (ASC, $$55) [cardinality: 58.0, 
doc-size: 15.0, op-cost: 0.0, total-cost: 789.76]
         -- STABLE_SORT [$$59(ASC), $$56(ASC), $$55(ASC)]  |PARTITIONED|
-          exchange [cardinality: 166.67, doc-size: 15.0, op-cost: 0.0, 
total-cost: 450.0]
+          exchange [cardinality: 58.0, doc-size: 15.0, op-cost: 0.0, 
total-cost: 450.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            project ([$$59, $$56, $$55]) [cardinality: 166.67, doc-size: 15.0, 
op-cost: 0.0, total-cost: 450.0]
+            project ([$$59, $$56, $$55]) [cardinality: 58.0, doc-size: 15.0, 
op-cost: 0.0, total-cost: 450.0]
             -- STREAM_PROJECT  |PARTITIONED|
-              exchange [cardinality: 166.67, doc-size: 15.0, op-cost: 0.0, 
total-cost: 450.0]
+              exchange [cardinality: 58.0, doc-size: 15.0, op-cost: 0.0, 
total-cost: 450.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                join (and(eq($$55, $$59), eq($$56, $$66))) [cardinality: 
166.67, doc-size: 15.0, op-cost: 180.0, total-cost: 450.0]
+                join (and(eq($$55, $$59), eq($$56, $$66))) [cardinality: 58.0, 
doc-size: 15.0, op-cost: 180.0, total-cost: 450.0]
                 -- HYBRID_HASH_JOIN [$$55, $$66][$$59, $$56]  |PARTITIONED|
                   exchange [cardinality: 150.0, doc-size: 5.0, op-cost: 0.0, 
total-cost: 150.0]
                   -- RANDOM_PARTITION_EXCHANGE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.007.plan
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.007.plan
index fcb9b9dc54..01957625c9 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.007.plan
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.007.plan
@@ -1,16 +1,16 @@
-distribute result [$$52] [cardinality: 6.0, doc-size: 15.0, op-cost: 0.0, 
total-cost: 39.51]
+distribute result [$$52] [cardinality: 2.1, doc-size: 15.0, op-cost: 0.0, 
total-cost: 22.35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 6.0, doc-size: 15.0, op-cost: 0.0, total-cost: 39.51]
+  exchange [cardinality: 2.1, doc-size: 15.0, op-cost: 0.0, total-cost: 22.35]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$52] <- [{"t1_id": $$53, "t2_id": $$54}] project: [$$52] 
[cardinality: 6.0, doc-size: 15.0, op-cost: 0.0, total-cost: 39.51]
+    assign [$$52] <- [{"t1_id": $$53, "t2_id": $$54}] project: [$$52] 
[cardinality: 2.1, doc-size: 15.0, op-cost: 0.0, total-cost: 22.35]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 6.0, doc-size: 15.0, op-cost: 0.0, total-cost: 
39.51]
+      exchange [cardinality: 2.1, doc-size: 15.0, op-cost: 0.0, total-cost: 
22.35]
       -- SORT_MERGE_EXCHANGE [$$53(ASC), $$54(ASC) ]  |PARTITIONED|
-        order (ASC, $$53) (ASC, $$54) [cardinality: 6.0, doc-size: 15.0, 
op-cost: 0.0, total-cost: 39.51]
+        order (ASC, $$53) (ASC, $$54) [cardinality: 2.1, doc-size: 15.0, 
op-cost: 0.0, total-cost: 22.35]
         -- STABLE_SORT [$$53(ASC), $$54(ASC)]  |PARTITIONED|
-          exchange [cardinality: 6.0, doc-size: 15.0, op-cost: 0.0, 
total-cost: 24.0]
+          exchange [cardinality: 2.1, doc-size: 15.0, op-cost: 0.0, 
total-cost: 20.1]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            select ($$62) project: [$$53, $$54] [cardinality: 6.0, doc-size: 
15.0, op-cost: 0.0, total-cost: 24.0]
+            select ($$62) project: [$$53, $$54] [cardinality: 2.1, doc-size: 
15.0, op-cost: 0.0, total-cost: 20.1]
             -- STREAM_SELECT  |PARTITIONED|
               window-aggregate [$$62] <- [win-mark-first-missing-impl($$54)] 
partition [$$53] order (DESC, $$54) [cardinality: 2.0, doc-size: 15.0, op-cost: 
0.0, total-cost: 2.0]
               -- WINDOW_STREAM  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.008.plan
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.008.plan
index 968c3f2279..36f2db582f 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.008.plan
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.008.plan
@@ -1,16 +1,16 @@
-distribute result [$$52] [cardinality: 6.0, doc-size: 15.0, op-cost: 0.0, 
total-cost: 39.51]
+distribute result [$$52] [cardinality: 2.1, doc-size: 15.0, op-cost: 0.0, 
total-cost: 22.35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 6.0, doc-size: 15.0, op-cost: 0.0, total-cost: 39.51]
+  exchange [cardinality: 2.1, doc-size: 15.0, op-cost: 0.0, total-cost: 22.35]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$52] <- [{"t1_id": $$53, "t2_id": $$54}] project: [$$52] 
[cardinality: 6.0, doc-size: 15.0, op-cost: 0.0, total-cost: 39.51]
+    assign [$$52] <- [{"t1_id": $$53, "t2_id": $$54}] project: [$$52] 
[cardinality: 2.1, doc-size: 15.0, op-cost: 0.0, total-cost: 22.35]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 6.0, doc-size: 15.0, op-cost: 0.0, total-cost: 
39.51]
+      exchange [cardinality: 2.1, doc-size: 15.0, op-cost: 0.0, total-cost: 
22.35]
       -- SORT_MERGE_EXCHANGE [$$53(ASC), $$54(ASC) ]  |PARTITIONED|
-        order (ASC, $$53) (ASC, $$54) [cardinality: 6.0, doc-size: 15.0, 
op-cost: 0.0, total-cost: 39.51]
+        order (ASC, $$53) (ASC, $$54) [cardinality: 2.1, doc-size: 15.0, 
op-cost: 0.0, total-cost: 22.35]
         -- STABLE_SORT [$$53(ASC), $$54(ASC)]  |PARTITIONED|
-          exchange [cardinality: 6.0, doc-size: 15.0, op-cost: 0.0, 
total-cost: 24.0]
+          exchange [cardinality: 2.1, doc-size: 15.0, op-cost: 0.0, 
total-cost: 20.1]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            select ($$62) project: [$$53, $$54] [cardinality: 6.0, doc-size: 
15.0, op-cost: 0.0, total-cost: 24.0]
+            select ($$62) project: [$$53, $$54] [cardinality: 2.1, doc-size: 
15.0, op-cost: 0.0, total-cost: 20.1]
             -- STREAM_SELECT  |PARTITIONED|
               window-aggregate [$$62] <- [win-mark-first-missing-impl($$54)] 
partition [$$53] order (DESC, $$54) [cardinality: 2.0, doc-size: 15.0, op-cost: 
0.0, total-cost: 2.0]
               -- WINDOW_STREAM  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.009.plan
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.009.plan
index f9554bc7c9..f3eb86dc8d 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.009.plan
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.009.plan
@@ -1,16 +1,16 @@
-distribute result [$$52] [cardinality: 6.0, doc-size: 15.0, op-cost: 0.0, 
total-cost: 39.51]
+distribute result [$$52] [cardinality: 2.1, doc-size: 15.0, op-cost: 0.0, 
total-cost: 22.35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 6.0, doc-size: 15.0, op-cost: 0.0, total-cost: 39.51]
+  exchange [cardinality: 2.1, doc-size: 15.0, op-cost: 0.0, total-cost: 22.35]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$52] <- [{"t1_id": $$53, "t2_id": $$54}] project: [$$52] 
[cardinality: 6.0, doc-size: 15.0, op-cost: 0.0, total-cost: 39.51]
+    assign [$$52] <- [{"t1_id": $$53, "t2_id": $$54}] project: [$$52] 
[cardinality: 2.1, doc-size: 15.0, op-cost: 0.0, total-cost: 22.35]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 6.0, doc-size: 15.0, op-cost: 0.0, total-cost: 
39.51]
+      exchange [cardinality: 2.1, doc-size: 15.0, op-cost: 0.0, total-cost: 
22.35]
       -- SORT_MERGE_EXCHANGE [$$53(ASC), $$54(ASC) ]  |PARTITIONED|
-        order (ASC, $$53) (ASC, $$54) [cardinality: 6.0, doc-size: 15.0, 
op-cost: 0.0, total-cost: 39.51]
+        order (ASC, $$53) (ASC, $$54) [cardinality: 2.1, doc-size: 15.0, 
op-cost: 0.0, total-cost: 22.35]
         -- STABLE_SORT [$$53(ASC), $$54(ASC)]  |PARTITIONED|
-          exchange [cardinality: 6.0, doc-size: 15.0, op-cost: 0.0, 
total-cost: 24.0]
+          exchange [cardinality: 2.1, doc-size: 15.0, op-cost: 0.0, 
total-cost: 20.1]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            select ($$62) project: [$$53, $$54] [cardinality: 6.0, doc-size: 
15.0, op-cost: 0.0, total-cost: 24.0]
+            select ($$62) project: [$$53, $$54] [cardinality: 2.1, doc-size: 
15.0, op-cost: 0.0, total-cost: 20.1]
             -- STREAM_SELECT  |PARTITIONED|
               window-aggregate [$$62] <- [win-mark-first-missing-impl($$54)] 
partition [$$53] order (DESC, $$54) [cardinality: 2.0, doc-size: 15.0, op-cost: 
0.0, total-cost: 2.0]
               -- WINDOW_STREAM  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.010.plan
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.010.plan
index e2e5a5c47a..aabe8e8d01 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.010.plan
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.010.plan
@@ -1,16 +1,16 @@
-distribute result [$$52] [cardinality: 6.0, doc-size: 15.0, op-cost: 0.0, 
total-cost: 39.51]
+distribute result [$$52] [cardinality: 2.1, doc-size: 15.0, op-cost: 0.0, 
total-cost: 22.35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 6.0, doc-size: 15.0, op-cost: 0.0, total-cost: 39.51]
+  exchange [cardinality: 2.1, doc-size: 15.0, op-cost: 0.0, total-cost: 22.35]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$52] <- [{"t1_id": $$53, "t2_id": $$54}] project: [$$52] 
[cardinality: 6.0, doc-size: 15.0, op-cost: 0.0, total-cost: 39.51]
+    assign [$$52] <- [{"t1_id": $$53, "t2_id": $$54}] project: [$$52] 
[cardinality: 2.1, doc-size: 15.0, op-cost: 0.0, total-cost: 22.35]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 6.0, doc-size: 15.0, op-cost: 0.0, total-cost: 
39.51]
+      exchange [cardinality: 2.1, doc-size: 15.0, op-cost: 0.0, total-cost: 
22.35]
       -- SORT_MERGE_EXCHANGE [$$53(ASC), $$54(ASC) ]  |PARTITIONED|
-        order (ASC, $$53) (ASC, $$54) [cardinality: 6.0, doc-size: 15.0, 
op-cost: 0.0, total-cost: 39.51]
+        order (ASC, $$53) (ASC, $$54) [cardinality: 2.1, doc-size: 15.0, 
op-cost: 0.0, total-cost: 22.35]
         -- STABLE_SORT [$$53(ASC), $$54(ASC)]  |PARTITIONED|
-          exchange [cardinality: 6.0, doc-size: 15.0, op-cost: 0.0, 
total-cost: 24.0]
+          exchange [cardinality: 2.1, doc-size: 15.0, op-cost: 0.0, 
total-cost: 20.1]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            select ($$62) project: [$$53, $$54] [cardinality: 6.0, doc-size: 
15.0, op-cost: 0.0, total-cost: 24.0]
+            select ($$62) project: [$$53, $$54] [cardinality: 2.1, doc-size: 
15.0, op-cost: 0.0, total-cost: 20.1]
             -- STREAM_SELECT  |PARTITIONED|
               window-aggregate [$$62] <- [win-mark-first-missing-impl($$54)] 
partition [$$53] order (DESC, $$54) [cardinality: 2.0, doc-size: 15.0, op-cost: 
0.0, total-cost: 2.0]
               -- WINDOW_STREAM  |PARTITIONED|
@@ -51,4 +51,4 @@ distribute result [$$52] [cardinality: 6.0, doc-size: 15.0, 
op-cost: 0.0, total-
                                                   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|
\ No newline at end of file
+                                                    -- EMPTY_TUPLE_SOURCE  
|PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/limit/push-limit-to-primary-scan-select/push-limit-to-primary-scan-select.5.plan
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/limit/push-limit-to-primary-scan-select/push-limit-to-primary-scan-select.5.plan
index c1343bf49f..0a1c6bb67d 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/limit/push-limit-to-primary-scan-select/push-limit-to-primary-scan-select.5.plan
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/limit/push-limit-to-primary-scan-select/push-limit-to-primary-scan-select.5.plan
@@ -1,20 +1,20 @@
-distribute result [$$37] [cardinality: 100.0, doc-size: 55.19, op-cost: 0.0, 
total-cost: 308.0]
+distribute result [$$37] [cardinality: 2.1, doc-size: 55.19, op-cost: 0.0, 
total-cost: 308.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
-  exchange [cardinality: 100.0, doc-size: 55.19, op-cost: 0.0, total-cost: 
308.0]
+  exchange [cardinality: 2.1, doc-size: 55.19, op-cost: 0.0, total-cost: 308.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
-    limit 2 [cardinality: 100.0, doc-size: 55.19, op-cost: 0.0, total-cost: 
308.0]
+    limit 2 [cardinality: 2.1, doc-size: 55.19, op-cost: 0.0, total-cost: 
308.0]
     -- STREAM_LIMIT  |UNPARTITIONED|
-      exchange [cardinality: 100.0, doc-size: 55.19, op-cost: 0.0, total-cost: 
308.0]
+      exchange [cardinality: 2.1, doc-size: 55.19, op-cost: 0.0, total-cost: 
308.0]
       -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
-        assign [$$37] <- [{"dblpid": $$38}] project: [$$37] [cardinality: 
100.0, doc-size: 55.19, op-cost: 0.0, total-cost: 308.0]
+        assign [$$37] <- [{"dblpid": $$38}] project: [$$37] [cardinality: 2.1, 
doc-size: 55.19, op-cost: 0.0, total-cost: 308.0]
         -- ASSIGN  |PARTITIONED|
-          limit 2 [cardinality: 100.0, doc-size: 55.19, op-cost: 0.0, 
total-cost: 308.0]
+          limit 2 [cardinality: 2.1, doc-size: 55.19, op-cost: 0.0, 
total-cost: 308.0]
           -- STREAM_LIMIT  |PARTITIONED|
-            project ([$$38]) [cardinality: 100.0, doc-size: 55.19, op-cost: 
0.0, total-cost: 308.0]
+            project ([$$38]) [cardinality: 2.1, doc-size: 55.19, op-cost: 0.0, 
total-cost: 308.0]
             -- STREAM_PROJECT  |PARTITIONED|
-              exchange [cardinality: 100.0, doc-size: 55.19, op-cost: 0.0, 
total-cost: 308.0]
+              exchange [cardinality: 2.1, doc-size: 55.19, op-cost: 0.0, 
total-cost: 308.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                join (eq($$38, $$41)) [cardinality: 100.0, doc-size: 55.19, 
op-cost: 104.0, total-cost: 308.0]
+                join (eq($$38, $$41)) [cardinality: 2.1, doc-size: 55.19, 
op-cost: 104.0, total-cost: 308.0]
                 -- HYBRID_HASH_JOIN [$$38][$$41]  |PARTITIONED|
                   exchange [cardinality: 100.0, doc-size: 27.19, op-cost: 0.0, 
total-cost: 100.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.10.plan
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.10.plan
index e7b9d0dd43..150ffb5c25 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.10.plan
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.10.plan
@@ -1,22 +1,22 @@
-distribute result [$$122] [cardinality: 104.81, doc-size: 50.0, op-cost: 0.0, 
total-cost: 1421245.07]
+distribute result [$$122] [cardinality: 22329.38, doc-size: 50.0, op-cost: 
0.0, total-cost: 1631364.19]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
-  exchange [cardinality: 104.81, doc-size: 50.0, op-cost: 0.0, total-cost: 
1421245.07]
+  exchange [cardinality: 22329.38, doc-size: 50.0, op-cost: 0.0, total-cost: 
1631364.19]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
-    assign [$$122] <- [{"$1": 9, "$2": $$140}] project: [$$122] [cardinality: 
104.81, doc-size: 50.0, op-cost: 0.0, total-cost: 1421245.07]
+    assign [$$122] <- [{"$1": 9, "$2": $$140}] project: [$$122] [cardinality: 
22329.38, doc-size: 50.0, op-cost: 0.0, total-cost: 1631364.19]
     -- ASSIGN  |UNPARTITIONED|
-      aggregate [$$140] <- [agg-sql-sum($$144)] [cardinality: 104.81, 
doc-size: 50.0, op-cost: 0.0, total-cost: 1421245.07]
+      aggregate [$$140] <- [agg-sql-sum($$144)] [cardinality: 22329.38, 
doc-size: 50.0, op-cost: 0.0, total-cost: 1631364.19]
       -- AGGREGATE  |UNPARTITIONED|
-        exchange [cardinality: 104.81, doc-size: 50.0, op-cost: 0.0, 
total-cost: 1421245.07]
+        exchange [cardinality: 22329.38, doc-size: 50.0, op-cost: 0.0, 
total-cost: 1631364.19]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
-          aggregate [$$144] <- [agg-sql-count(1)] [cardinality: 104.81, 
doc-size: 50.0, op-cost: 0.0, total-cost: 1421245.07]
+          aggregate [$$144] <- [agg-sql-count(1)] [cardinality: 22329.38, 
doc-size: 50.0, op-cost: 0.0, total-cost: 1631364.19]
           -- AGGREGATE  |PARTITIONED|
-            exchange [cardinality: 104.81, doc-size: 50.0, op-cost: 0.0, 
total-cost: 1421245.07]
+            exchange [cardinality: 22329.38, doc-size: 50.0, op-cost: 0.0, 
total-cost: 1631364.19]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              unnest-map [$$136, $$o] <- index-search("orders", 0, "Default", 
"tpch", "orders", true, true, 1, $$132, 1, $$132, true, true, true) 
[cardinality: 104.81, doc-size: 50.0, op-cost: 0.0, total-cost: 1421245.07]
+              unnest-map [$$136, $$o] <- index-search("orders", 0, "Default", 
"tpch", "orders", true, true, 1, $$132, 1, $$132, true, true, true) 
[cardinality: 22329.38, doc-size: 50.0, op-cost: 0.0, total-cost: 1631364.19]
               -- BTREE_SEARCH  |PARTITIONED|
                 exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  order (ASC, $$132) [cardinality: 104.81, doc-size: 50.0, 
op-cost: 523.57, total-cost: 1421245.07]
+                  order (ASC, $$132) [cardinality: 22329.38, doc-size: 50.0, 
op-cost: 111541.96, total-cost: 1631364.19]
                   -- STABLE_SORT [$$132(ASC)]  |PARTITIONED|
                     exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
                     -- HASH_PARTITION_EXCHANGE [$$132]  |PARTITIONED|
@@ -24,52 +24,40 @@ distribute result [$$122] [cardinality: 104.81, doc-size: 
50.0, op-cost: 0.0, to
                       -- STREAM_PROJECT  |PARTITIONED|
                         exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          join (eq($$138, $$137)) [cardinality: 104.71, 
doc-size: 45.0, op-cost: 129.71, total-cost: 1420302.63]
-                          -- HYBRID_HASH_JOIN [$$138][$$137]  |PARTITIONED|
+                          join (and(eq($$135, $$128), eq($$134, $$125))) 
[cardinality: 22308.39, doc-size: 45.0, op-cost: 615114.82, total-cost: 
1430588.67]
+                          -- HYBRID_HASH_JOIN [$$128, $$125][$$135, $$134]  
|PARTITIONED|
                             exchange [cardinality: 0.0, doc-size: 0.0, 
op-cost: 0.0, total-cost: 0.0]
-                            -- HASH_PARTITION_EXCHANGE [$$138]  |PARTITIONED|
-                              project ([$$138, $$132]) [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              assign [$$128, $$125] <- [$$l.getField(2), 
$$l.getField(1)] project: [$$132, $$128, $$125] [cardinality: 0.0, doc-size: 
0.0, op-cost: 0.0, total-cost: 0.0]
+                              -- ASSIGN  |PARTITIONED|
+                                project ([$$132, $$l]) [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 []<-[$$131, $$132, $$l] <- 
tpch.lineitem [cardinality: 600572.0, doc-size: 15.0, op-cost: 600572.0, 
total-cost: 600572.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|
+                              project ([$$134, $$135]) [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|
-                                  join (eq($$130, $$135)) [cardinality: 
104.71, doc-size: 40.0, op-cost: 1411.38, total-cost: 1420018.2]
-                                  -- HYBRID_HASH_JOIN [$$130][$$135]  
|PARTITIONED|
+                                  join (eq($$138, $$137)) [cardinality: 
3494.46, doc-size: 30.0, op-cost: 3594.46, total-cost: 200924.01]
+                                  -- HYBRID_HASH_JOIN [$$138][$$137]  
|PARTITIONED|
                                     exchange [cardinality: 0.0, doc-size: 0.0, 
op-cost: 0.0, total-cost: 0.0]
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      assign [$$138] <- [$$s.getField(3)] 
project: [$$130, $$138] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
-                                      -- ASSIGN  |PARTITIONED|
-                                        exchange [cardinality: 0.0, doc-size: 
0.0, op-cost: 0.0, total-cost: 0.0]
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          data-scan []<-[$$130, $$s] <- 
tpch.supplier [cardinality: 1000.0, doc-size: 10.0, op-cost: 1000.0, 
total-cost: 1000.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|
-                                      project ([$$132, $$135]) [cardinality: 
0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                      project ([$$134, $$135, $$138]) 
[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|
-                                          join (and(eq($$135, $$128), 
eq($$134, $$125))) [cardinality: 106.09, doc-size: 30.0, op-cost: 615298.92, 
total-cost: 1417182.45]
-                                          -- HYBRID_HASH_JOIN [$$128, 
$$125][$$135, $$134]  |PARTITIONED|
-                                            exchange [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                            -- ONE_TO_ONE_EXCHANGE  
|PARTITIONED|
-                                              assign [$$128, $$125] <- 
[$$l.getField(2), $$l.getField(1)] project: [$$132, $$128, $$125] [cardinality: 
0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                              -- ASSIGN  |PARTITIONED|
-                                                project ([$$132, $$l]) 
[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 []<-[$$131, 
$$132, $$l] <- tpch.lineitem [cardinality: 600572.0, doc-size: 15.0, op-cost: 
600572.0, total-cost: 600572.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|
+                                          join (eq($$130, $$135)) 
[cardinality: 3494.46, doc-size: 25.0, op-cost: 4527.49, total-cost: 197204.55]
+                                          -- HYBRID_HASH_JOIN [$$135][$$130]  
|PARTITIONED|
                                             exchange [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                            -- BROADCAST_EXCHANGE  
|PARTITIONED|
+                                            -- HASH_PARTITION_EXCHANGE [$$135] 
 |PARTITIONED|
                                               project ([$$134, $$135]) 
[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]
@@ -100,15 +88,27 @@ distribute result [$$122] [cardinality: 104.81, doc-size: 
50.0, op-cost: 0.0, to
                                                             -- 
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]
-                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              project ([$$137]) [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 []<-[$$137, $$n] <- tpch.nation 
[cardinality: 25.0, doc-size: 5.0, op-cost: 25.0, total-cost: 25.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|
+                                              assign [$$138] <- 
[$$s.getField(3)] project: [$$130, $$138] [cardinality: 0.0, doc-size: 0.0, 
op-cost: 0.0, total-cost: 0.0]
+                                              -- ASSIGN  |PARTITIONED|
+                                                exchange [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                -- ONE_TO_ONE_EXCHANGE  
|PARTITIONED|
+                                                  data-scan []<-[$$130, $$s] 
<- tpch.supplier [cardinality: 1000.0, doc-size: 10.0, op-cost: 1000.0, 
total-cost: 1000.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]
-                                    -- 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|
+                                    -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                      project ([$$137]) [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 []<-[$$137, $$n] <- 
tpch.nation [cardinality: 25.0, doc-size: 5.0, op-cost: 25.0, total-cost: 25.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|

Reply via email to