[ASTERIX-3376][COMP] Choose smaller side's sample

Change-Id: I63445673ba10782d85717b780c07687db8f8011f
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/18254
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Vijay Sarathy <vijay.sarathy@couchbase.com>
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 785da69..574e207 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
@@ -163,12 +163,21 @@
                 return productivity / card1;
             }
         } else {
-            ILogicalOperator leafInput = joinEnum.leafInputs.get(idx2 - 1); // we arbitrarily pick one side
+            ILogicalOperator leafInput;
+            LogicalVariable var;
+            // choose the smaller side sample; better results this way for sure!
+            if (card1 < card2) {
+                leafInput = joinEnum.leafInputs.get(idx1 - 1);
+                var = exprUsedVars.get(0);
+            } else {
+                leafInput = joinEnum.leafInputs.get(idx2 - 1);
+                var = exprUsedVars.get(1);
+            }
             Index index = findIndex(leafInput);
             if (index == null) {
                 return 1.0;
             }
-            List<List<IAObject>> result = runSamplingQueryDistinct(this.optCtx, leafInput, exprUsedVars.get(1), index);
+            List<List<IAObject>> result = runSamplingQueryDistinct(this.optCtx, leafInput, var, index);
             if (result == null) {
                 return 1.0;
             }
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 c769ae2..5e89200 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,36 +1,36 @@
-distribute result [$$119] [cardinality: 25.0, op-cost: 0.0, total-cost: 9097.68]
+distribute result [$$119] [cardinality: 25.0, op-cost: 0.0, total-cost: 7223.81]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 25.0, op-cost: 0.0, total-cost: 9097.68]
+  exchange [cardinality: 25.0, op-cost: 0.0, total-cost: 7223.81]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$119]) [cardinality: 25.0, op-cost: 0.0, total-cost: 9097.68]
+    project ([$$119]) [cardinality: 25.0, op-cost: 0.0, total-cost: 7223.81]
     -- STREAM_PROJECT  |PARTITIONED|
-      assign [$$119] <- [{"n_name": $$n_name, "revenue": $$132}] [cardinality: 25.0, op-cost: 0.0, total-cost: 9097.68]
+      assign [$$119] <- [{"n_name": $$n_name, "revenue": $$132}] [cardinality: 25.0, op-cost: 0.0, total-cost: 7223.81]
       -- ASSIGN  |PARTITIONED|
-        exchange [cardinality: 25.0, op-cost: 0.0, total-cost: 9097.68]
+        exchange [cardinality: 25.0, op-cost: 0.0, total-cost: 7223.81]
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
           group by ([$$n_name := $$142]) decor ([]) {
                     aggregate [$$132] <- [global-sql-sum-serial($$141)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                     -- AGGREGATE  |LOCAL|
                       nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                 } [cardinality: 25.0, op-cost: 64.54, total-cost: 9097.68]
+                 } [cardinality: 25.0, op-cost: 110.34, total-cost: 7223.81]
           -- EXTERNAL_GROUP_BY[$$142]  |PARTITIONED|
-            exchange [cardinality: 25.0, op-cost: 0.0, total-cost: 9033.14]
+            exchange [cardinality: 25.0, op-cost: 0.0, total-cost: 7113.47]
             -- 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, op-cost: 0.0, total-cost: 0.0]
                         -- AGGREGATE  |LOCAL|
                           nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                     } [cardinality: 25.0, op-cost: 64.54, total-cost: 9033.14]
+                     } [cardinality: 25.0, op-cost: 110.34, total-cost: 7113.47]
               -- EXTERNAL_GROUP_BY[$$120]  |PARTITIONED|
-                exchange [cardinality: 64.54, op-cost: 0.0, total-cost: 8968.6]
+                exchange [cardinality: 110.34, op-cost: 0.0, total-cost: 7003.13]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  project ([$$139, $$140, $$120]) [cardinality: 64.54, op-cost: 0.0, total-cost: 8968.6]
+                  project ([$$139, $$140, $$120]) [cardinality: 110.34, op-cost: 0.0, total-cost: 7003.13]
                   -- STREAM_PROJECT  |PARTITIONED|
-                    exchange [cardinality: 64.54, op-cost: 0.0, total-cost: 8968.6]
+                    exchange [cardinality: 110.34, op-cost: 0.0, total-cost: 7003.13]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      join (and(eq($$130, $$128), eq($$133, $$127))) [cardinality: 64.54, op-cost: 1554.23, total-cost: 8968.6]
+                      join (and(eq($$130, $$128), eq($$133, $$127))) [cardinality: 110.34, op-cost: 1062.24, total-cost: 7003.13]
                       -- HYBRID_HASH_JOIN [$$128, $$133][$$130, $$127]  |PARTITIONED|
                         exchange [cardinality: 6010.65, op-cost: 0.0, total-cost: 6005.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
@@ -50,7 +50,7 @@
                                       -- STREAM_PROJECT  |PARTITIONED|
                                         exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          join (eq($$123, $$136)) [cardinality: 377.77, op-cost: 402.2, total-cost: 2829.4]
+                                          join (eq($$123, $$136)) [cardinality: 255.03, op-cost: 402.2, total-cost: 2829.4]
                                           -- HYBRID_HASH_JOIN [$$123][$$136]  |PARTITIONED|
                                             exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                             -- HASH_PARTITION_EXCHANGE [$$123]  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.008.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.008.plan
index 2bf5a05..9022614 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.008.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.008.plan
@@ -1,24 +1,24 @@
-distribute result [$$31] [cardinality: 7.11, op-cost: 0.0, total-cost: 65.12]
+distribute result [$$31] [cardinality: 9.33, op-cost: 0.0, total-cost: 75.06]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 7.11, op-cost: 0.0, total-cost: 65.12]
+  exchange [cardinality: 9.33, op-cost: 0.0, total-cost: 75.06]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$31]) [cardinality: 7.11, op-cost: 0.0, total-cost: 65.12]
+    project ([$$31]) [cardinality: 9.33, op-cost: 0.0, total-cost: 75.06]
     -- STREAM_PROJECT  |PARTITIONED|
-      assign [$$31] <- [{"age": $$38, "name": $$39}] [cardinality: 7.11, op-cost: 0.0, total-cost: 65.12]
+      assign [$$31] <- [{"age": $$38, "name": $$39}] [cardinality: 9.33, op-cost: 0.0, total-cost: 75.06]
       -- ASSIGN  |PARTITIONED|
-        project ([$$38, $$39]) [cardinality: 7.11, op-cost: 0.0, total-cost: 65.12]
+        project ([$$38, $$39]) [cardinality: 9.33, op-cost: 0.0, total-cost: 75.06]
         -- STREAM_PROJECT  |PARTITIONED|
-          exchange [cardinality: 7.11, op-cost: 0.0, total-cost: 65.12]
+          exchange [cardinality: 9.33, op-cost: 0.0, total-cost: 75.06]
           -- SORT_MERGE_EXCHANGE [$$34(ASC) ]  |PARTITIONED|
-            order (ASC, $$34) [cardinality: 7.11, op-cost: 20.12, total-cost: 65.12]
+            order (ASC, $$34) [cardinality: 9.33, op-cost: 30.06, total-cost: 75.06]
             -- STABLE_SORT [$$34(ASC)]  |PARTITIONED|
-              exchange [cardinality: 7.11, op-cost: 0.0, total-cost: 45.0]
+              exchange [cardinality: 9.33, op-cost: 0.0, total-cost: 45.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                project ([$$38, $$39, $$34]) [cardinality: 7.11, op-cost: 0.0, total-cost: 45.0]
+                project ([$$38, $$39, $$34]) [cardinality: 9.33, op-cost: 0.0, total-cost: 45.0]
                 -- STREAM_PROJECT  |PARTITIONED|
-                  exchange [cardinality: 7.11, op-cost: 0.0, total-cost: 45.0]
+                  exchange [cardinality: 9.33, op-cost: 0.0, total-cost: 45.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    join (eq($$33, $$34)) [cardinality: 7.11, op-cost: 15.0, total-cost: 45.0]
+                    join (eq($$33, $$34)) [cardinality: 9.33, op-cost: 15.0, total-cost: 45.0]
                     -- HYBRID_HASH_JOIN [$$34][$$33]  |PARTITIONED|
                       exchange [cardinality: 8.0, op-cost: 8.0, total-cost: 16.0]
                       -- HASH_PARTITION_EXCHANGE [$$34]  |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 40fb0c0..f4c4a85 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,66 +1,64 @@
-distribute result [$$51] [cardinality: 62.1, op-cost: 0.0, total-cost: 852.21]
+distribute result [$$51] [cardinality: 159.84, op-cost: 0.0, total-cost: 1777.06]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 62.1, op-cost: 0.0, total-cost: 852.21]
+  exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 1777.06]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$51]) [cardinality: 62.1, op-cost: 0.0, total-cost: 852.21]
+    project ([$$51]) [cardinality: 159.84, op-cost: 0.0, total-cost: 1777.06]
     -- STREAM_PROJECT  |PARTITIONED|
-      assign [$$51] <- [{"n_nationkey": $$58, "s_nationkey": $$56, "c_nationkey": $$55}] [cardinality: 62.1, op-cost: 0.0, total-cost: 852.21]
+      assign [$$51] <- [{"n_nationkey": $$58, "s_nationkey": $$56, "c_nationkey": $$55}] [cardinality: 159.84, op-cost: 0.0, total-cost: 1777.06]
       -- ASSIGN  |PARTITIONED|
-        exchange [cardinality: 62.1, op-cost: 0.0, total-cost: 852.21]
+        exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 1777.06]
         -- SORT_MERGE_EXCHANGE [$$58(ASC), $$56(ASC), $$55(ASC) ]  |PARTITIONED|
-          order (ASC, $$58) (ASC, $$56) (ASC, $$55) [cardinality: 62.1, op-cost: 369.9, total-cost: 852.21]
+          order (ASC, $$58) (ASC, $$56) (ASC, $$55) [cardinality: 159.84, op-cost: 1170.11, total-cost: 1777.06]
           -- STABLE_SORT [$$58(ASC), $$56(ASC), $$55(ASC)]  |PARTITIONED|
-            exchange [cardinality: 62.1, op-cost: 0.0, total-cost: 482.31]
+            exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 606.95]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              project ([$$58, $$56, $$55]) [cardinality: 62.1, op-cost: 0.0, total-cost: 482.31]
-              -- STREAM_PROJECT  |PARTITIONED|
-                exchange [cardinality: 62.1, op-cost: 0.0, total-cost: 482.31]
-                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  join (and(eq($$55, $$58), eq($$56, $$66))) [cardinality: 62.1, op-cost: 191.03, total-cost: 482.31]
-                  -- HYBRID_HASH_JOIN [$$55, $$66][$$58, $$56]  |PARTITIONED|
-                    exchange [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
-                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      assign [$$66] <- [$$55] [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
-                      -- ASSIGN  |PARTITIONED|
-                        project ([$$55]) [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
-                        -- STREAM_PROJECT  |PARTITIONED|
-                          assign [$$55] <- [$$c.getField(3)] [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
-                          -- ASSIGN  |PARTITIONED|
-                            project ([$$c]) [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
-                            -- STREAM_PROJECT  |PARTITIONED|
-                              exchange [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
-                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                data-scan []<-[$$60, $$c] <- tpch.Customer [cardinality: 150.0, op-cost: 150.0, total-cost: 150.0]
-                                -- DATASOURCE_SCAN  |PARTITIONED|
-                                  exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                    exchange [cardinality: 10.26, op-cost: 41.03, total-cost: 141.29]
-                    -- BROADCAST_EXCHANGE  |PARTITIONED|
-                      project ([$$56, $$58]) [cardinality: 10.26, op-cost: 0.0, total-cost: 100.26]
+              join (eq($$55, $$58)) [cardinality: 159.84, op-cost: 175.97, total-cost: 606.95]
+              -- HYBRID_HASH_JOIN [$$55][$$58]  |PARTITIONED|
+                exchange [cardinality: 150.0, op-cost: 150.0, total-cost: 300.0]
+                -- HASH_PARTITION_EXCHANGE [$$55]  |PARTITIONED|
+                  project ([$$55]) [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    assign [$$55] <- [$$c.getField(3)] [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
+                    -- ASSIGN  |PARTITIONED|
+                      project ([$$c]) [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
                       -- STREAM_PROJECT  |PARTITIONED|
-                        exchange [cardinality: 10.26, op-cost: 41.03, total-cost: 141.29]
+                        exchange [cardinality: 150.0, op-cost: 150.0, total-cost: 300.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          unnest-map [$$58, $$n] <- index-search("Nation", 0, "Default", "tpch", "Nation", true, true, 1, $$56, 1, $$56, true, true, true) [cardinality: 10.26, op-cost: 50.26, total-cost: 100.26]
-                          -- BTREE_SEARCH  |PARTITIONED|
+                          data-scan []<-[$$60, $$c] <- tpch.Customer [cardinality: 150.0, op-cost: 150.0, total-cost: 150.0]
+                          -- DATASOURCE_SCAN  |PARTITIONED|
                             exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              order (ASC, $$56) [cardinality: 10.26, op-cost: 50.26, total-cost: 100.26]
-                              -- STABLE_SORT [$$56(ASC)]  |PARTITIONED|
+                              empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange [cardinality: 25.97, op-cost: 25.97, total-cost: 130.97]
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  join (eq($$56, $$58)) [cardinality: 25.97, op-cost: 35.0, total-cost: 105.0]
+                  -- HYBRID_HASH_JOIN [$$58][$$56]  |PARTITIONED|
+                    exchange [cardinality: 25.0, op-cost: 25.0, total-cost: 50.0]
+                    -- HASH_PARTITION_EXCHANGE [$$58]  |PARTITIONED|
+                      project ([$$58]) [cardinality: 25.0, op-cost: 0.0, total-cost: 25.0]
+                      -- STREAM_PROJECT  |PARTITIONED|
+                        exchange [cardinality: 25.0, op-cost: 25.0, total-cost: 50.0]
+                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          data-scan []<-[$$58, $$n] <- tpch.Nation [cardinality: 25.0, op-cost: 25.0, total-cost: 25.0]
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange [cardinality: 10.0, op-cost: 10.0, total-cost: 20.0]
+                    -- HASH_PARTITION_EXCHANGE [$$56]  |PARTITIONED|
+                      project ([$$56]) [cardinality: 10.0, op-cost: 0.0, total-cost: 10.0]
+                      -- STREAM_PROJECT  |PARTITIONED|
+                        assign [$$56] <- [$$s.getField(3)] [cardinality: 10.0, op-cost: 0.0, total-cost: 10.0]
+                        -- ASSIGN  |PARTITIONED|
+                          project ([$$s]) [cardinality: 10.0, op-cost: 0.0, total-cost: 10.0]
+                          -- STREAM_PROJECT  |PARTITIONED|
+                            exchange [cardinality: 10.0, op-cost: 10.0, total-cost: 20.0]
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              data-scan []<-[$$59, $$s] <- tpch.Supplier [cardinality: 10.0, op-cost: 10.0, total-cost: 10.0]
+                              -- DATASOURCE_SCAN  |PARTITIONED|
                                 exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                -- HASH_PARTITION_EXCHANGE [$$56]  |PARTITIONED|
-                                  project ([$$56]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                  -- STREAM_PROJECT  |PARTITIONED|
-                                    assign [$$56] <- [$$s.getField(3)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                    -- ASSIGN  |PARTITIONED|
-                                      project ([$$s]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                      -- STREAM_PROJECT  |PARTITIONED|
-                                        exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          data-scan []<-[$$59, $$s] <- tpch.Supplier [cardinality: 10.0, op-cost: 10.0, total-cost: 10.0]
-                                          -- DATASOURCE_SCAN  |PARTITIONED|
-                                            exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                  -- EMPTY_TUPLE_SOURCE  |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 f032041..c2a7593 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,66 +1,64 @@
-distribute result [$$51] [cardinality: 62.1, op-cost: 0.0, total-cost: 821.69]
+distribute result [$$51] [cardinality: 159.84, op-cost: 0.0, total-cost: 1730.95]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 62.1, op-cost: 0.0, total-cost: 821.69]
+  exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 1730.95]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$51]) [cardinality: 62.1, op-cost: 0.0, total-cost: 821.69]
+    project ([$$51]) [cardinality: 159.84, op-cost: 0.0, total-cost: 1730.95]
     -- STREAM_PROJECT  |PARTITIONED|
-      assign [$$51] <- [{"n_nationkey": $$58, "s_nationkey": $$56, "c_nationkey": $$55}] [cardinality: 62.1, op-cost: 0.0, total-cost: 821.69]
+      assign [$$51] <- [{"n_nationkey": $$58, "s_nationkey": $$56, "c_nationkey": $$55}] [cardinality: 159.84, op-cost: 0.0, total-cost: 1730.95]
       -- ASSIGN  |PARTITIONED|
-        exchange [cardinality: 62.1, op-cost: 0.0, total-cost: 821.69]
+        exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 1730.95]
         -- SORT_MERGE_EXCHANGE [$$58(ASC), $$56(ASC), $$55(ASC) ]  |PARTITIONED|
-          order (ASC, $$58) (ASC, $$56) (ASC, $$55) [cardinality: 62.1, op-cost: 369.9, total-cost: 821.69]
+          order (ASC, $$58) (ASC, $$56) (ASC, $$55) [cardinality: 159.84, op-cost: 1170.11, total-cost: 1730.95]
           -- STABLE_SORT [$$58(ASC), $$56(ASC), $$55(ASC)]  |PARTITIONED|
-            exchange [cardinality: 62.1, op-cost: 0.0, total-cost: 451.79]
+            exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 560.84]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              project ([$$58, $$56, $$55]) [cardinality: 62.1, op-cost: 0.0, total-cost: 451.79]
-              -- STREAM_PROJECT  |PARTITIONED|
-                exchange [cardinality: 62.1, op-cost: 0.0, total-cost: 451.79]
-                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  join (and(eq($$55, $$58), eq($$56, $$66))) [cardinality: 62.1, op-cost: 180.77, total-cost: 451.79]
-                  -- HYBRID_HASH_JOIN [$$55, $$66][$$58, $$56]  |PARTITIONED|
-                    exchange [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
-                    -- RANDOM_PARTITION_EXCHANGE  |PARTITIONED|
-                      assign [$$66] <- [$$55] [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
-                      -- ASSIGN  |PARTITIONED|
-                        project ([$$55]) [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
-                        -- STREAM_PROJECT  |PARTITIONED|
-                          assign [$$55] <- [$$c.getField(3)] [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
-                          -- ASSIGN  |PARTITIONED|
-                            project ([$$c]) [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
-                            -- STREAM_PROJECT  |PARTITIONED|
-                              exchange [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
-                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                data-scan []<-[$$60, $$c] <- tpch.Customer [cardinality: 150.0, op-cost: 150.0, total-cost: 150.0]
-                                -- DATASOURCE_SCAN  |PARTITIONED|
-                                  exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                    exchange [cardinality: 10.26, op-cost: 30.77, total-cost: 121.03]
-                    -- BROADCAST_EXCHANGE  |PARTITIONED|
-                      project ([$$56, $$58]) [cardinality: 10.26, op-cost: 0.0, total-cost: 90.26]
+              join (eq($$55, $$58)) [cardinality: 159.84, op-cost: 227.92, total-cost: 560.84]
+              -- HYBRID_HASH_JOIN [$$55][$$58]  |PARTITIONED|
+                exchange [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
+                -- RANDOM_PARTITION_EXCHANGE  |PARTITIONED|
+                  project ([$$55]) [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    assign [$$55] <- [$$c.getField(3)] [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
+                    -- ASSIGN  |PARTITIONED|
+                      project ([$$c]) [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
                       -- STREAM_PROJECT  |PARTITIONED|
-                        exchange [cardinality: 10.26, op-cost: 30.77, total-cost: 121.03]
+                        exchange [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          unnest-map [$$58, $$n] <- index-search("Nation", 0, "Default", "tpch", "Nation", true, true, 1, $$56, 1, $$56, true, true, true) [cardinality: 10.26, op-cost: 50.26, total-cost: 90.26]
-                          -- BTREE_SEARCH  |PARTITIONED|
+                          data-scan []<-[$$60, $$c] <- tpch.Customer [cardinality: 150.0, op-cost: 150.0, total-cost: 150.0]
+                          -- DATASOURCE_SCAN  |PARTITIONED|
                             exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              order (ASC, $$56) [cardinality: 10.26, op-cost: 50.26, total-cost: 90.26]
-                              -- STABLE_SORT [$$56(ASC)]  |PARTITIONED|
+                              empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange [cardinality: 25.97, op-cost: 77.92, total-cost: 182.92]
+                -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  join (eq($$56, $$58)) [cardinality: 25.97, op-cost: 35.0, total-cost: 105.0]
+                  -- HYBRID_HASH_JOIN [$$58][$$56]  |PARTITIONED|
+                    exchange [cardinality: 25.0, op-cost: 25.0, total-cost: 50.0]
+                    -- HASH_PARTITION_EXCHANGE [$$58]  |PARTITIONED|
+                      project ([$$58]) [cardinality: 25.0, op-cost: 0.0, total-cost: 25.0]
+                      -- STREAM_PROJECT  |PARTITIONED|
+                        exchange [cardinality: 25.0, op-cost: 25.0, total-cost: 50.0]
+                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          data-scan []<-[$$58, $$n] <- tpch.Nation [cardinality: 25.0, op-cost: 25.0, total-cost: 25.0]
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange [cardinality: 10.0, op-cost: 10.0, total-cost: 20.0]
+                    -- HASH_PARTITION_EXCHANGE [$$56]  |PARTITIONED|
+                      project ([$$56]) [cardinality: 10.0, op-cost: 0.0, total-cost: 10.0]
+                      -- STREAM_PROJECT  |PARTITIONED|
+                        assign [$$56] <- [$$s.getField(3)] [cardinality: 10.0, op-cost: 0.0, total-cost: 10.0]
+                        -- ASSIGN  |PARTITIONED|
+                          project ([$$s]) [cardinality: 10.0, op-cost: 0.0, total-cost: 10.0]
+                          -- STREAM_PROJECT  |PARTITIONED|
+                            exchange [cardinality: 10.0, op-cost: 10.0, total-cost: 20.0]
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              data-scan []<-[$$59, $$s] <- tpch.Supplier [cardinality: 10.0, op-cost: 10.0, total-cost: 10.0]
+                              -- DATASOURCE_SCAN  |PARTITIONED|
                                 exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                -- HASH_PARTITION_EXCHANGE [$$56]  |PARTITIONED|
-                                  project ([$$56]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                  -- STREAM_PROJECT  |PARTITIONED|
-                                    assign [$$56] <- [$$s.getField(3)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                    -- ASSIGN  |PARTITIONED|
-                                      project ([$$s]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                      -- STREAM_PROJECT  |PARTITIONED|
-                                        exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          data-scan []<-[$$59, $$s] <- tpch.Supplier [cardinality: 10.0, op-cost: 10.0, total-cost: 10.0]
-                                          -- DATASOURCE_SCAN  |PARTITIONED|
-                                            exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                  -- EMPTY_TUPLE_SOURCE  |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 55c4214..2e075a1 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,22 +1,22 @@
-distribute result [$$51] [cardinality: 62.1, op-cost: 0.0, total-cost: 945.41]
+distribute result [$$51] [cardinality: 159.84, op-cost: 0.0, total-cost: 1777.06]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 62.1, op-cost: 0.0, total-cost: 945.41]
+  exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 1777.06]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$51]) [cardinality: 62.1, op-cost: 0.0, total-cost: 945.41]
+    project ([$$51]) [cardinality: 159.84, op-cost: 0.0, total-cost: 1777.06]
     -- STREAM_PROJECT  |PARTITIONED|
-      assign [$$51] <- [{"n_nationkey": $$58, "s_nationkey": $$56, "c_nationkey": $$55}] [cardinality: 62.1, op-cost: 0.0, total-cost: 945.41]
+      assign [$$51] <- [{"n_nationkey": $$58, "s_nationkey": $$56, "c_nationkey": $$55}] [cardinality: 159.84, op-cost: 0.0, total-cost: 1777.06]
       -- ASSIGN  |PARTITIONED|
-        exchange [cardinality: 62.1, op-cost: 0.0, total-cost: 945.41]
+        exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 1777.06]
         -- SORT_MERGE_EXCHANGE [$$58(ASC), $$56(ASC), $$55(ASC) ]  |PARTITIONED|
-          order (ASC, $$58) (ASC, $$56) (ASC, $$55) [cardinality: 62.1, op-cost: 369.9, total-cost: 945.41]
+          order (ASC, $$58) (ASC, $$56) (ASC, $$55) [cardinality: 159.84, op-cost: 1170.11, total-cost: 1777.06]
           -- STABLE_SORT [$$58(ASC), $$56(ASC), $$55(ASC)]  |PARTITIONED|
-            exchange [cardinality: 62.1, op-cost: 0.0, total-cost: 575.51]
+            exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 606.95]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              join (eq($$55, $$58)) [cardinality: 62.1, op-cost: 160.26, total-cost: 575.51]
+              join (eq($$55, $$58)) [cardinality: 159.84, op-cost: 175.97, total-cost: 606.95]
               -- HYBRID_HASH_JOIN [$$58][$$55]  |PARTITIONED|
-                exchange [cardinality: 10.26, op-cost: 10.26, total-cost: 115.26]
+                exchange [cardinality: 25.97, op-cost: 25.97, total-cost: 130.97]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  join (eq($$56, $$58)) [cardinality: 10.26, op-cost: 35.0, total-cost: 105.0]
+                  join (eq($$56, $$58)) [cardinality: 25.97, op-cost: 35.0, total-cost: 105.0]
                   -- HYBRID_HASH_JOIN [$$58][$$56]  |PARTITIONED|
                     exchange [cardinality: 25.0, op-cost: 25.0, total-cost: 50.0]
                     -- HASH_PARTITION_EXCHANGE [$$58]  |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 e6d2791..9ca57cc 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,25 +1,25 @@
-distribute result [$$51] [cardinality: 62.1, op-cost: 0.0, total-cost: 852.21]
+distribute result [$$51] [cardinality: 159.84, op-cost: 0.0, total-cost: 1788.03]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 62.1, op-cost: 0.0, total-cost: 852.21]
+  exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 1788.03]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$51]) [cardinality: 62.1, op-cost: 0.0, total-cost: 852.21]
+    project ([$$51]) [cardinality: 159.84, op-cost: 0.0, total-cost: 1788.03]
     -- STREAM_PROJECT  |PARTITIONED|
-      assign [$$51] <- [{"n_nationkey": $$59, "s_nationkey": $$56, "c_nationkey": $$55}] [cardinality: 62.1, op-cost: 0.0, total-cost: 852.21]
+      assign [$$51] <- [{"n_nationkey": $$59, "s_nationkey": $$56, "c_nationkey": $$55}] [cardinality: 159.84, op-cost: 0.0, total-cost: 1788.03]
       -- ASSIGN  |PARTITIONED|
-        exchange [cardinality: 62.1, op-cost: 0.0, total-cost: 852.21]
+        exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 1788.03]
         -- SORT_MERGE_EXCHANGE [$$59(ASC), $$56(ASC), $$55(ASC) ]  |PARTITIONED|
-          order (ASC, $$59) (ASC, $$56) (ASC, $$55) [cardinality: 62.1, op-cost: 369.9, total-cost: 852.21]
+          order (ASC, $$59) (ASC, $$56) (ASC, $$55) [cardinality: 159.84, op-cost: 1170.11, total-cost: 1788.03]
           -- STABLE_SORT [$$59(ASC), $$56(ASC), $$55(ASC)]  |PARTITIONED|
-            exchange [cardinality: 62.1, op-cost: 0.0, total-cost: 482.31]
+            exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 617.92]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              project ([$$59, $$56, $$55]) [cardinality: 62.1, op-cost: 0.0, total-cost: 482.31]
+              project ([$$59, $$56, $$55]) [cardinality: 159.84, op-cost: 0.0, total-cost: 617.92]
               -- STREAM_PROJECT  |PARTITIONED|
-                exchange [cardinality: 62.1, op-cost: 0.0, total-cost: 482.31]
+                exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 617.92]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  join (and(eq($$55, $$59), eq($$56, $$66))) [cardinality: 62.1, op-cost: 191.03, total-cost: 482.31]
+                  join (and(eq($$55, $$59), eq($$56, $$66))) [cardinality: 159.84, op-cost: 175.97, total-cost: 617.92]
                   -- HYBRID_HASH_JOIN [$$55, $$66][$$59, $$56]  |PARTITIONED|
-                    exchange [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
-                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    exchange [cardinality: 150.0, op-cost: 150.0, total-cost: 300.0]
+                    -- HASH_PARTITION_EXCHANGE [$$55, $$66]  |PARTITIONED|
                       assign [$$66] <- [$$55] [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
                       -- ASSIGN  |PARTITIONED|
                         project ([$$55]) [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
@@ -28,7 +28,7 @@
                           -- ASSIGN  |PARTITIONED|
                             project ([$$c]) [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
                             -- STREAM_PROJECT  |PARTITIONED|
-                              exchange [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
+                              exchange [cardinality: 150.0, op-cost: 150.0, total-cost: 300.0]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                 data-scan []<-[$$60, $$c] <- tpch.Customer [cardinality: 150.0, op-cost: 150.0, total-cost: 150.0]
                                 -- DATASOURCE_SCAN  |PARTITIONED|
@@ -36,17 +36,17 @@
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                     empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                    exchange [cardinality: 10.26, op-cost: 41.03, total-cost: 141.29]
-                    -- BROADCAST_EXCHANGE  |PARTITIONED|
-                      project ([$$56, $$59]) [cardinality: 10.26, op-cost: 0.0, total-cost: 100.26]
+                    exchange [cardinality: 25.97, op-cost: 25.97, total-cost: 141.94]
+                    -- HASH_PARTITION_EXCHANGE [$$59, $$56]  |PARTITIONED|
+                      project ([$$56, $$59]) [cardinality: 25.97, op-cost: 0.0, total-cost: 115.97]
                       -- STREAM_PROJECT  |PARTITIONED|
-                        exchange [cardinality: 10.26, op-cost: 41.03, total-cost: 141.29]
+                        exchange [cardinality: 25.97, op-cost: 25.97, total-cost: 141.94]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          unnest-map [$$59, $$n] <- index-search("Nation", 0, "Default", "tpch", "Nation", true, true, 1, $$56, 1, $$56, true, true, true) [cardinality: 10.26, op-cost: 50.26, total-cost: 100.26]
+                          unnest-map [$$59, $$n] <- index-search("Nation", 0, "Default", "tpch", "Nation", true, true, 1, $$56, 1, $$56, true, true, true) [cardinality: 25.97, op-cost: 65.97, total-cost: 115.97]
                           -- BTREE_SEARCH  |PARTITIONED|
                             exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              order (ASC, $$56) [cardinality: 10.26, op-cost: 50.26, total-cost: 100.26]
+                              order (ASC, $$56) [cardinality: 25.97, op-cost: 65.97, total-cost: 115.97]
                               -- STABLE_SORT [$$56(ASC)]  |PARTITIONED|
                                 exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                 -- HASH_PARTITION_EXCHANGE [$$56]  |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 8491a35..dd41dfc 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,22 +1,22 @@
-distribute result [$$51] [cardinality: 62.1, op-cost: 0.0, total-cost: 821.69]
+distribute result [$$51] [cardinality: 159.84, op-cost: 0.0, total-cost: 1731.93]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 62.1, op-cost: 0.0, total-cost: 821.69]
+  exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 1731.93]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$51]) [cardinality: 62.1, op-cost: 0.0, total-cost: 821.69]
+    project ([$$51]) [cardinality: 159.84, op-cost: 0.0, total-cost: 1731.93]
     -- STREAM_PROJECT  |PARTITIONED|
-      assign [$$51] <- [{"n_nationkey": $$59, "s_nationkey": $$56, "c_nationkey": $$55}] [cardinality: 62.1, op-cost: 0.0, total-cost: 821.69]
+      assign [$$51] <- [{"n_nationkey": $$59, "s_nationkey": $$56, "c_nationkey": $$55}] [cardinality: 159.84, op-cost: 0.0, total-cost: 1731.93]
       -- ASSIGN  |PARTITIONED|
-        exchange [cardinality: 62.1, op-cost: 0.0, total-cost: 821.69]
+        exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 1731.93]
         -- SORT_MERGE_EXCHANGE [$$59(ASC), $$56(ASC), $$55(ASC) ]  |PARTITIONED|
-          order (ASC, $$59) (ASC, $$56) (ASC, $$55) [cardinality: 62.1, op-cost: 369.9, total-cost: 821.69]
+          order (ASC, $$59) (ASC, $$56) (ASC, $$55) [cardinality: 159.84, op-cost: 1170.11, total-cost: 1731.93]
           -- STABLE_SORT [$$59(ASC), $$56(ASC), $$55(ASC)]  |PARTITIONED|
-            exchange [cardinality: 62.1, op-cost: 0.0, total-cost: 451.79]
+            exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 561.82]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              project ([$$59, $$56, $$55]) [cardinality: 62.1, op-cost: 0.0, total-cost: 451.79]
+              project ([$$59, $$56, $$55]) [cardinality: 159.84, op-cost: 0.0, total-cost: 561.82]
               -- STREAM_PROJECT  |PARTITIONED|
-                exchange [cardinality: 62.1, op-cost: 0.0, total-cost: 451.79]
+                exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 561.82]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  join (and(eq($$55, $$59), eq($$56, $$66))) [cardinality: 62.1, op-cost: 180.77, total-cost: 451.79]
+                  join (and(eq($$55, $$59), eq($$56, $$66))) [cardinality: 159.84, op-cost: 227.92, total-cost: 561.82]
                   -- HYBRID_HASH_JOIN [$$55, $$66][$$59, $$56]  |PARTITIONED|
                     exchange [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
                     -- RANDOM_PARTITION_EXCHANGE  |PARTITIONED|
@@ -36,17 +36,17 @@
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                     empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                    exchange [cardinality: 10.26, op-cost: 30.77, total-cost: 121.03]
+                    exchange [cardinality: 25.97, op-cost: 77.92, total-cost: 183.89]
                     -- BROADCAST_EXCHANGE  |PARTITIONED|
-                      project ([$$56, $$59]) [cardinality: 10.26, op-cost: 0.0, total-cost: 90.26]
+                      project ([$$56, $$59]) [cardinality: 25.97, op-cost: 0.0, total-cost: 105.97]
                       -- STREAM_PROJECT  |PARTITIONED|
-                        exchange [cardinality: 10.26, op-cost: 30.77, total-cost: 121.03]
+                        exchange [cardinality: 25.97, op-cost: 77.92, total-cost: 183.89]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          unnest-map [$$59, $$n] <- index-search("Nation", 0, "Default", "tpch", "Nation", true, true, 1, $$56, 1, $$56, true, true, true) [cardinality: 10.26, op-cost: 50.26, total-cost: 90.26]
+                          unnest-map [$$59, $$n] <- index-search("Nation", 0, "Default", "tpch", "Nation", true, true, 1, $$56, 1, $$56, true, true, true) [cardinality: 25.97, op-cost: 65.97, total-cost: 105.97]
                           -- BTREE_SEARCH  |PARTITIONED|
                             exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              order (ASC, $$56) [cardinality: 10.26, op-cost: 50.26, total-cost: 90.26]
+                              order (ASC, $$56) [cardinality: 25.97, op-cost: 65.97, total-cost: 105.97]
                               -- STABLE_SORT [$$56(ASC)]  |PARTITIONED|
                                 exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                 -- HASH_PARTITION_EXCHANGE [$$56]  |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 1361fdb..17d8f1c 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,20 +1,20 @@
-distribute result [$$52] [cardinality: 3.0, op-cost: 0.0, total-cost: 25.75]
+distribute result [$$52] [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 3.0, op-cost: 0.0, total-cost: 25.75]
+  exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$52]) [cardinality: 3.0, op-cost: 0.0, total-cost: 25.75]
+    project ([$$52]) [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
     -- STREAM_PROJECT  |PARTITIONED|
-      assign [$$52] <- [{"t1_id": $$53, "t2_id": $$54}] [cardinality: 3.0, op-cost: 0.0, total-cost: 25.75]
+      assign [$$52] <- [{"t1_id": $$53, "t2_id": $$54}] [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
       -- ASSIGN  |PARTITIONED|
-        exchange [cardinality: 3.0, op-cost: 0.0, total-cost: 25.75]
+        exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
         -- SORT_MERGE_EXCHANGE [$$53(ASC), $$54(ASC) ]  |PARTITIONED|
-          order (ASC, $$53) (ASC, $$54) [cardinality: 3.0, op-cost: 4.75, total-cost: 25.75]
+          order (ASC, $$53) (ASC, $$54) [cardinality: 4.0, op-cost: 8.0, total-cost: 30.0]
           -- STABLE_SORT [$$53(ASC), $$54(ASC)]  |PARTITIONED|
-            exchange [cardinality: 3.0, op-cost: 0.0, total-cost: 21.0]
+            exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 22.0]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              project ([$$53, $$54]) [cardinality: 3.0, op-cost: 0.0, total-cost: 21.0]
+              project ([$$53, $$54]) [cardinality: 4.0, op-cost: 0.0, total-cost: 22.0]
               -- STREAM_PROJECT  |PARTITIONED|
-                select ($$62) [cardinality: 3.0, op-cost: 11.0, total-cost: 21.0]
+                select ($$62) [cardinality: 4.0, op-cost: 12.0, total-cost: 22.0]
                 -- STREAM_SELECT  |PARTITIONED|
                   window-aggregate [$$62] <- [win-mark-first-missing-impl($$54)] partition [$$53] order (DESC, $$54) [cardinality: 2.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 ce7648e..66414a5 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,20 +1,20 @@
-distribute result [$$52] [cardinality: 3.0, op-cost: 0.0, total-cost: 25.75]
+distribute result [$$52] [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 3.0, op-cost: 0.0, total-cost: 25.75]
+  exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$52]) [cardinality: 3.0, op-cost: 0.0, total-cost: 25.75]
+    project ([$$52]) [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
     -- STREAM_PROJECT  |PARTITIONED|
-      assign [$$52] <- [{"t1_id": $$73, "t2_id": $$54}] [cardinality: 3.0, op-cost: 0.0, total-cost: 25.75]
+      assign [$$52] <- [{"t1_id": $$73, "t2_id": $$54}] [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
       -- ASSIGN  |PARTITIONED|
-        exchange [cardinality: 3.0, op-cost: 0.0, total-cost: 25.75]
+        exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
         -- SORT_MERGE_EXCHANGE [$$73(ASC), $$54(ASC) ]  |PARTITIONED|
-          order (ASC, $$73) (ASC, $$54) [cardinality: 3.0, op-cost: 4.75, total-cost: 25.75]
+          order (ASC, $$73) (ASC, $$54) [cardinality: 4.0, op-cost: 8.0, total-cost: 30.0]
           -- STABLE_SORT [$$73(ASC), $$54(ASC)]  |PARTITIONED|
-            exchange [cardinality: 3.0, op-cost: 0.0, total-cost: 21.0]
+            exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 22.0]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              project ([$$73, $$54]) [cardinality: 3.0, op-cost: 0.0, total-cost: 21.0]
+              project ([$$73, $$54]) [cardinality: 4.0, op-cost: 0.0, total-cost: 22.0]
               -- STREAM_PROJECT  |PARTITIONED|
-                select ($$74) [cardinality: 3.0, op-cost: 11.0, total-cost: 21.0]
+                select ($$74) [cardinality: 4.0, op-cost: 12.0, total-cost: 22.0]
                 -- STREAM_SELECT  |PARTITIONED|
                   window-aggregate [$$74] <- [win-mark-first-missing-impl($$54)] partition [$$73] order (DESC, $$54) [cardinality: 2.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 354bace..814461c 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,20 +1,20 @@
-distribute result [$$52] [cardinality: 3.0, op-cost: 0.0, total-cost: 25.75]
+distribute result [$$52] [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 3.0, op-cost: 0.0, total-cost: 25.75]
+  exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$52]) [cardinality: 3.0, op-cost: 0.0, total-cost: 25.75]
+    project ([$$52]) [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
     -- STREAM_PROJECT  |PARTITIONED|
-      assign [$$52] <- [{"t1_id": $$53, "t2_id": $$54}] [cardinality: 3.0, op-cost: 0.0, total-cost: 25.75]
+      assign [$$52] <- [{"t1_id": $$53, "t2_id": $$54}] [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
       -- ASSIGN  |PARTITIONED|
-        exchange [cardinality: 3.0, op-cost: 0.0, total-cost: 25.75]
+        exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
         -- SORT_MERGE_EXCHANGE [$$53(ASC), $$54(ASC) ]  |PARTITIONED|
-          order (ASC, $$53) (ASC, $$54) [cardinality: 3.0, op-cost: 4.75, total-cost: 25.75]
+          order (ASC, $$53) (ASC, $$54) [cardinality: 4.0, op-cost: 8.0, total-cost: 30.0]
           -- STABLE_SORT [$$53(ASC), $$54(ASC)]  |PARTITIONED|
-            exchange [cardinality: 3.0, op-cost: 0.0, total-cost: 21.0]
+            exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 22.0]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              project ([$$53, $$54]) [cardinality: 3.0, op-cost: 0.0, total-cost: 21.0]
+              project ([$$53, $$54]) [cardinality: 4.0, op-cost: 0.0, total-cost: 22.0]
               -- STREAM_PROJECT  |PARTITIONED|
-                select ($$62) [cardinality: 3.0, op-cost: 11.0, total-cost: 21.0]
+                select ($$62) [cardinality: 4.0, op-cost: 12.0, total-cost: 22.0]
                 -- STREAM_SELECT  |PARTITIONED|
                   window-aggregate [$$62] <- [win-mark-first-missing-impl($$54)] partition [$$53] order (DESC, $$54) [cardinality: 2.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 0e7b3a6..a6e0902 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,20 +1,20 @@
-distribute result [$$52] [cardinality: 3.0, op-cost: 0.0, total-cost: 25.75]
+distribute result [$$52] [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 3.0, op-cost: 0.0, total-cost: 25.75]
+  exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$52]) [cardinality: 3.0, op-cost: 0.0, total-cost: 25.75]
+    project ([$$52]) [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
     -- STREAM_PROJECT  |PARTITIONED|
-      assign [$$52] <- [{"t1_id": $$73, "t2_id": $$54}] [cardinality: 3.0, op-cost: 0.0, total-cost: 25.75]
+      assign [$$52] <- [{"t1_id": $$73, "t2_id": $$54}] [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
       -- ASSIGN  |PARTITIONED|
-        exchange [cardinality: 3.0, op-cost: 0.0, total-cost: 25.75]
+        exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
         -- SORT_MERGE_EXCHANGE [$$73(ASC), $$54(ASC) ]  |PARTITIONED|
-          order (ASC, $$73) (ASC, $$54) [cardinality: 3.0, op-cost: 4.75, total-cost: 25.75]
+          order (ASC, $$73) (ASC, $$54) [cardinality: 4.0, op-cost: 8.0, total-cost: 30.0]
           -- STABLE_SORT [$$73(ASC), $$54(ASC)]  |PARTITIONED|
-            exchange [cardinality: 3.0, op-cost: 0.0, total-cost: 21.0]
+            exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 22.0]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              project ([$$73, $$54]) [cardinality: 3.0, op-cost: 0.0, total-cost: 21.0]
+              project ([$$73, $$54]) [cardinality: 4.0, op-cost: 0.0, total-cost: 22.0]
               -- STREAM_PROJECT  |PARTITIONED|
-                select ($$74) [cardinality: 3.0, op-cost: 11.0, total-cost: 21.0]
+                select ($$74) [cardinality: 4.0, op-cost: 12.0, total-cost: 22.0]
                 -- STREAM_SELECT  |PARTITIONED|
                   window-aggregate [$$74] <- [win-mark-first-missing-impl($$54)] partition [$$73] order (DESC, $$54) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
                   -- WINDOW_STREAM  |PARTITIONED|