From f40c962fc8be46dda97320837934cfd66c653d58 Mon Sep 17 00:00:00 2001 From: Rebecca Taft Date: Mon, 28 Jun 2021 11:58:50 -0500 Subject: [PATCH] opt: add cost penalty for scans with large cardinality This commit adds a new cost function, largeCardinalityRowCountPenalty, which calculates a penalty that should be added to the row count of scans. It is non-zero for expressions with unbounded maximum cardinality or with maximum cardinality exceeding the row count estimate. Adding a few rows worth of cost helps prevent surprising plans for very small tables or for when stats are stale. Fixes #64570 Release note (performance improvement): When choosing between index scans that are estimated to have the same number of rows, the optimizer now prefers indexes for which it has higher certainty about the maximum number of rows over indexes for which there is more uncertainty in the estimated row count. This helps to avoid choosing suboptimal plans for small tables or if the statistics are stale. --- .../testdata/logic_test/alter_primary_key | 4 +- pkg/sql/logictest/testdata/logic_test/prepare | 4 +- .../testdata/logic_test/vectorize_local | 10 +- .../opt/exec/execbuilder/testdata/aggregate | 8 +- .../opt/exec/execbuilder/testdata/distsql_agg | 4 +- pkg/sql/opt/exec/execbuilder/testdata/explain | 34 +- .../exec/execbuilder/testdata/inverted_index | 24 +- pkg/sql/opt/exec/execbuilder/testdata/stats | 16 +- pkg/sql/opt/memo/testdata/format | 30 +- pkg/sql/opt/memo/testdata/memo | 62 +-- pkg/sql/opt/memo/testdata/stats/inverted-geo | 44 +-- pkg/sql/opt/memo/testdata/stats/join | 20 +- pkg/sql/opt/norm/testdata/rules/combo | 118 +++--- pkg/sql/opt/norm/testdata/rules/prune_cols | 16 +- pkg/sql/opt/norm/testdata/rules/scalar | 8 +- pkg/sql/opt/norm/testdata/rules/with | 8 +- pkg/sql/opt/optbuilder/testdata/aggregate | 6 +- pkg/sql/opt/optgen/exprgen/testdata/explain | 22 +- pkg/sql/opt/optgen/exprgen/testdata/join | 30 +- pkg/sql/opt/optgen/exprgen/testdata/limit | 6 +- pkg/sql/opt/optgen/exprgen/testdata/scan | 10 +- pkg/sql/opt/props/cardinality.go | 5 + .../testutils/opttester/testdata/opt-steps | 58 +-- pkg/sql/opt/xform/coster.go | 45 +++ pkg/sql/opt/xform/testdata/coster/groupby | 4 +- pkg/sql/opt/xform/testdata/coster/join | 82 ++-- .../opt/xform/testdata/coster/perturb-cost | 8 +- pkg/sql/opt/xform/testdata/coster/project | 8 +- pkg/sql/opt/xform/testdata/coster/scan | 165 +++++++- pkg/sql/opt/xform/testdata/coster/select | 12 +- pkg/sql/opt/xform/testdata/coster/set | 36 +- pkg/sql/opt/xform/testdata/coster/sort | 30 +- .../opt/xform/testdata/coster/virtual-scan | 4 +- pkg/sql/opt/xform/testdata/coster/zone | 86 ++-- pkg/sql/opt/xform/testdata/physprops/ordering | 72 ++-- pkg/sql/opt/xform/testdata/rules/groupby | 366 +++++++++--------- pkg/sql/opt/xform/testdata/rules/join | 264 +++++++------ pkg/sql/opt/xform/testdata/rules/join_order | 122 +++--- pkg/sql/opt/xform/testdata/rules/scan | 40 +- pkg/sql/opt/xform/testdata/rules/select | 337 ++++++++-------- 40 files changed, 1225 insertions(+), 1003 deletions(-) diff --git a/pkg/sql/logictest/testdata/logic_test/alter_primary_key b/pkg/sql/logictest/testdata/logic_test/alter_primary_key index 82d846e63033..93686c975675 100644 --- a/pkg/sql/logictest/testdata/logic_test/alter_primary_key +++ b/pkg/sql/logictest/testdata/logic_test/alter_primary_key @@ -118,7 +118,7 @@ SELECT * FROM parent 4 5 query T -SELECT * FROM [EXPLAIN SELECT * FROM child WHERE x >= 1 AND x < 5 AND y >= 2 AND y <= 6] OFFSET 2 +SELECT * FROM [EXPLAIN SELECT * FROM child@primary WHERE x >= 1 AND x < 5 AND y >= 2 AND y <= 6] OFFSET 2 ---- · • filter @@ -130,7 +130,7 @@ SELECT * FROM [EXPLAIN SELECT * FROM child WHERE x >= 1 AND x < 5 AND y >= 2 AND spans: [/1/2 - /4/6] query III rowsort -SELECT * FROM child WHERE x >= 1 AND x < 5 AND y >= 2 AND y <= 6 +SELECT * FROM child@primary WHERE x >= 1 AND x < 5 AND y >= 2 AND y <= 6 ---- 1 2 3 4 5 6 diff --git a/pkg/sql/logictest/testdata/logic_test/prepare b/pkg/sql/logictest/testdata/logic_test/prepare index 97a00815cb5e..53768c2e15ec 100644 --- a/pkg/sql/logictest/testdata/logic_test/prepare +++ b/pkg/sql/logictest/testdata/logic_test/prepare @@ -1171,14 +1171,14 @@ select ├── columns: k:1 str:2 ├── immutable ├── stats: [rows=333.333333] - ├── cost: 1064.43 + ├── cost: 1074.83 ├── key: (1) ├── fd: (1)-->(2) ├── prune: (2) ├── scan t2 │ ├── columns: k:1 str:2 │ ├── stats: [rows=1000] - │ ├── cost: 1054.41 + │ ├── cost: 1064.81 │ ├── key: (1) │ ├── fd: (1)-->(2) │ └── prune: (1,2) diff --git a/pkg/sql/logictest/testdata/logic_test/vectorize_local b/pkg/sql/logictest/testdata/logic_test/vectorize_local index 9fb22aa89e60..9b9f885769b2 100644 --- a/pkg/sql/logictest/testdata/logic_test/vectorize_local +++ b/pkg/sql/logictest/testdata/logic_test/vectorize_local @@ -98,7 +98,7 @@ EXPLAIN (OPT, VERBOSE) SELECT c.a FROM c INNER MERGE JOIN d ON c.a = d.b project ├── columns: a:1 ├── stats: [rows=10] - ├── cost: 1100.77 + ├── cost: 1122.17 ├── prune: (1) └── inner-join (merge) ├── columns: c.a:1 d.b:8 @@ -106,12 +106,12 @@ project ├── left ordering: +1 ├── right ordering: +8 ├── stats: [rows=10, distinct(1)=1, null(1)=0, distinct(8)=1, null(8)=0] - ├── cost: 1100.66 + ├── cost: 1122.06 ├── fd: (1)==(8), (8)==(1) ├── sort │ ├── columns: c.a:1 │ ├── stats: [rows=1, distinct(1)=1, null(1)=0] - │ ├── cost: 15.93 + │ ├── cost: 26.73 │ ├── ordering: +1 │ ├── prune: (1) │ ├── interesting orderings: (+1) @@ -119,14 +119,14 @@ project │ └── scan c@sec │ ├── columns: c.a:1 │ ├── stats: [rows=1, distinct(1)=1, null(1)=0] - │ ├── cost: 15.89 + │ ├── cost: 26.69 │ ├── prune: (1) │ ├── interesting orderings: (+1) │ └── unfiltered-cols: (1-6) ├── scan d │ ├── columns: d.b:8 │ ├── stats: [rows=1000, distinct(8)=100, null(8)=0] - │ ├── cost: 1074.61 + │ ├── cost: 1085.21 │ ├── ordering: +8 │ ├── prune: (8) │ ├── interesting orderings: (+8) diff --git a/pkg/sql/opt/exec/execbuilder/testdata/aggregate b/pkg/sql/opt/exec/execbuilder/testdata/aggregate index 72ca6b147ea6..2ae235a00668 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/aggregate +++ b/pkg/sql/opt/exec/execbuilder/testdata/aggregate @@ -670,7 +670,7 @@ vectorized: true • group (scalar) │ columns: (min int) │ estimated row count: 1 (missing stats) -│ aggregate 0: min(x) +│ aggregate 0: any_not_null(x) │ └── • project │ columns: (x int) @@ -680,6 +680,7 @@ vectorized: true estimated row count: 1 (missing stats) table: xyz@zyx spans: /3/2-/3/3 + limit: 1 statement ok SET tracing = on,kv,results; SELECT min(x) FROM xyz WHERE (y, z) = (2, 3.0); SET tracing = off @@ -701,16 +702,17 @@ vectorized: true • group (scalar) │ columns: (max int) │ estimated row count: 1 (missing stats) -│ aggregate 0: max(x) +│ aggregate 0: any_not_null(x) │ └── • project │ columns: (x int) │ - └── • scan + └── • revscan columns: (x int, y int, z float) estimated row count: 1 (missing stats) table: xyz@zyx spans: /3/2-/3/3 + limit: 1 # VARIANCE/STDDEV diff --git a/pkg/sql/opt/exec/execbuilder/testdata/distsql_agg b/pkg/sql/opt/exec/execbuilder/testdata/distsql_agg index ae4aa4e6346b..b3e131743209 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/distsql_agg +++ b/pkg/sql/opt/exec/execbuilder/testdata/distsql_agg @@ -962,7 +962,7 @@ group-by ├── grouping columns: b:2 ├── internal-ordering: +2 opt(1) ├── stats: [rows=9.5617925, distinct(2)=9.5617925, null(2)=0] - ├── cost: 15.1256179 + ├── cost: 25.9256179 ├── key: (2) ├── fd: (2)-->(5) ├── prune: (5) @@ -970,7 +970,7 @@ group-by │ ├── columns: a:1 b:2 │ ├── constraint: /1/2: [/1 - /1] │ ├── stats: [rows=10, distinct(1)=1, null(1)=0, distinct(2)=9.5617925, null(2)=0] - │ ├── cost: 14.81 + │ ├── cost: 25.61 │ ├── key: (2) │ ├── fd: ()-->(1) │ ├── ordering: +2 opt(1) [actual: +2] diff --git a/pkg/sql/opt/exec/execbuilder/testdata/explain b/pkg/sql/opt/exec/execbuilder/testdata/explain index 2c647232f503..af2e37a933c0 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/explain +++ b/pkg/sql/opt/exec/execbuilder/testdata/explain @@ -1097,7 +1097,7 @@ EXPLAIN (OPT,VERBOSE) SELECT * FROM tc WHERE a = 10 ORDER BY b sort ├── columns: a:1 b:2 ├── stats: [rows=10, distinct(1)=1, null(1)=0] - ├── cost: 76.7943856 + ├── cost: 87.5943856 ├── fd: ()-->(1) ├── ordering: +2 opt(1) [actual: +2] ├── prune: (2) @@ -1105,7 +1105,7 @@ sort └── index-join tc ├── columns: a:1 b:2 ├── stats: [rows=10, distinct(1)=1, null(1)=0] - ├── cost: 75.72 + ├── cost: 86.52 ├── fd: ()-->(1) ├── prune: (2) ├── interesting orderings: (+1) @@ -1113,7 +1113,7 @@ sort ├── columns: a:1 rowid:3 ├── constraint: /1/3: [/10 - /10] ├── stats: [rows=10, distinct(1)=1, null(1)=0] - ├── cost: 14.81 + ├── cost: 25.61 ├── key: (3) └── fd: ()-->(1) @@ -1123,7 +1123,7 @@ EXPLAIN (OPT,TYPES) SELECT * FROM tc WHERE a = 10 ORDER BY b sort ├── columns: a:1(int!null) b:2(int) ├── stats: [rows=10, distinct(1)=1, null(1)=0] - ├── cost: 76.7943856 + ├── cost: 87.5943856 ├── fd: ()-->(1) ├── ordering: +2 opt(1) [actual: +2] ├── prune: (2) @@ -1131,7 +1131,7 @@ sort └── index-join tc ├── columns: a:1(int!null) b:2(int) ├── stats: [rows=10, distinct(1)=1, null(1)=0] - ├── cost: 75.72 + ├── cost: 86.52 ├── fd: ()-->(1) ├── prune: (2) ├── interesting orderings: (+1) @@ -1139,7 +1139,7 @@ sort ├── columns: a:1(int!null) rowid:3(int!null) ├── constraint: /1/3: [/10 - /10] ├── stats: [rows=10, distinct(1)=1, null(1)=0] - ├── cost: 14.81 + ├── cost: 25.61 ├── key: (3) └── fd: ()-->(1) @@ -1187,20 +1187,20 @@ inner-join (hash) ├── columns: a:1 b:2 k:6 v:7 ├── multiplicity: left-rows(zero-or-one), right-rows(zero-or-more) ├── stats: [rows=990, distinct(1)=99, null(1)=0, distinct(6)=99, null(6)=0] - ├── cost: 2249.74 + ├── cost: 2271.54 ├── fd: (6)-->(7), (1)==(6), (6)==(1) ├── prune: (2,7) ├── scan tc │ ├── columns: a:1 b:2 │ ├── stats: [rows=1000, distinct(1)=100, null(1)=10] - │ ├── cost: 1115.01 + │ ├── cost: 1126.01 │ ├── prune: (1,2) │ ├── interesting orderings: (+1) │ └── unfiltered-cols: (1-5) ├── scan t │ ├── columns: k:6 v:7 │ ├── stats: [rows=1000, distinct(6)=1000, null(6)=0] - │ ├── cost: 1094.81 + │ ├── cost: 1105.61 │ ├── key: (6) │ ├── fd: (6)-->(7) │ ├── prune: (6,7) @@ -1228,7 +1228,7 @@ sort ├── columns: a:1 b:2 [hidden: column6:6] ├── immutable ├── stats: [rows=333.333333] - ├── cost: 1204.25548 + ├── cost: 1215.25548 ├── fd: (1,2)-->(6) ├── ordering: +6 ├── prune: (1,2,6) @@ -1237,7 +1237,7 @@ sort ├── columns: column6:6 a:1 b:2 ├── immutable ├── stats: [rows=333.333333] - ├── cost: 1131.70667 + ├── cost: 1142.70667 ├── fd: (1,2)-->(6) ├── prune: (1,2,6) ├── interesting orderings: (+1) @@ -1245,12 +1245,12 @@ sort │ ├── columns: a:1 b:2 │ ├── immutable │ ├── stats: [rows=333.333333] - │ ├── cost: 1125.03 + │ ├── cost: 1136.03 │ ├── interesting orderings: (+1) │ ├── scan tc │ │ ├── columns: a:1 b:2 │ │ ├── stats: [rows=1000] - │ │ ├── cost: 1115.01 + │ │ ├── cost: 1126.01 │ │ ├── prune: (1,2) │ │ └── interesting orderings: (+1) │ └── filters @@ -1265,7 +1265,7 @@ sort ├── columns: a:1(int) b:2(int) [hidden: column6:6(int)] ├── immutable ├── stats: [rows=333.333333] - ├── cost: 1204.25548 + ├── cost: 1215.25548 ├── fd: (1,2)-->(6) ├── ordering: +6 ├── prune: (1,2,6) @@ -1274,7 +1274,7 @@ sort ├── columns: column6:6(int) a:1(int) b:2(int) ├── immutable ├── stats: [rows=333.333333] - ├── cost: 1131.70667 + ├── cost: 1142.70667 ├── fd: (1,2)-->(6) ├── prune: (1,2,6) ├── interesting orderings: (+1) @@ -1282,12 +1282,12 @@ sort │ ├── columns: a:1(int) b:2(int) │ ├── immutable │ ├── stats: [rows=333.333333] - │ ├── cost: 1125.03 + │ ├── cost: 1136.03 │ ├── interesting orderings: (+1) │ ├── scan tc │ │ ├── columns: a:1(int) b:2(int) │ │ ├── stats: [rows=1000] - │ │ ├── cost: 1115.01 + │ │ ├── cost: 1126.01 │ │ ├── prune: (1,2) │ │ └── interesting orderings: (+1) │ └── filters diff --git a/pkg/sql/opt/exec/execbuilder/testdata/inverted_index b/pkg/sql/opt/exec/execbuilder/testdata/inverted_index index 7541978e3b18..dd3a3c8efa29 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/inverted_index +++ b/pkg/sql/opt/exec/execbuilder/testdata/inverted_index @@ -939,7 +939,7 @@ inner-join (lookup geo_table) ├── lookup columns are key ├── immutable ├── stats: [rows=9801] - ├── cost: 112694.84 + ├── cost: 112705.64 ├── key: (1,5) ├── fd: (1)-->(2), (5)-->(6) ├── prune: (1,5) @@ -948,13 +948,13 @@ inner-join (lookup geo_table) │ ├── inverted-expr │ │ └── st_intersects(geo_table2.geom:2, geo_table.geom:12) │ ├── stats: [rows=10000, distinct(1)=999.956829, null(1)=0, distinct(11)=999.956829, null(11)=0] - │ ├── cost: 41794.82 + │ ├── cost: 41805.62 │ ├── key: (1,11) │ ├── fd: (1)-->(2) │ ├── scan geo_table2 │ │ ├── columns: geo_table2.k:1 geo_table2.geom:2 │ │ ├── stats: [rows=1000, distinct(1)=1000, null(1)=0, distinct(2)=100, null(2)=10] - │ │ ├── cost: 1094.81 + │ │ ├── cost: 1105.61 │ │ ├── key: (1) │ │ ├── fd: (1)-->(2) │ │ ├── prune: (1,2) @@ -1029,7 +1029,7 @@ left-join (lookup geo_table) ├── second join in paired joiner ├── immutable ├── stats: [rows=10000] - ├── cost: 112894.84 + ├── cost: 112905.64 ├── key: (1,5) ├── fd: (1)-->(2), (5)-->(6) ├── prune: (1,5) @@ -1039,13 +1039,13 @@ left-join (lookup geo_table) │ ├── inverted-expr │ │ └── st_intersects(geo_table2.geom:2, geo_table.geom:12) │ ├── stats: [rows=10000, distinct(1)=1000, null(1)=0, distinct(11)=999.956829, null(11)=0] - │ ├── cost: 41994.82 + │ ├── cost: 42005.62 │ ├── key: (1,11) │ ├── fd: (1)-->(2), (11)-->(16) │ ├── scan geo_table2 │ │ ├── columns: geo_table2.k:1 geo_table2.geom:2 │ │ ├── stats: [rows=1000, distinct(1)=1000, null(1)=0] - │ │ ├── cost: 1094.81 + │ │ ├── cost: 1105.61 │ │ ├── key: (1) │ │ ├── fd: (1)-->(2) │ │ ├── prune: (1,2) @@ -1065,7 +1065,7 @@ semi-join (lookup geo_table) ├── second join in paired joiner ├── immutable ├── stats: [rows=10] - ├── cost: 112694.84 + ├── cost: 112705.64 ├── key: (1) ├── fd: (1)-->(2) ├── prune: (1) @@ -1075,13 +1075,13 @@ semi-join (lookup geo_table) │ ├── inverted-expr │ │ └── st_intersects(geo_table2.geom:2, geo_table.geom:12) │ ├── stats: [rows=10000, distinct(1)=999.956829, null(1)=0, distinct(11)=999.956829, null(11)=0] - │ ├── cost: 41994.82 + │ ├── cost: 42005.62 │ ├── key: (1,11) │ ├── fd: (1)-->(2), (11)-->(16) │ ├── scan geo_table2 │ │ ├── columns: geo_table2.k:1 geo_table2.geom:2 │ │ ├── stats: [rows=1000, distinct(1)=1000, null(1)=0, distinct(2)=100, null(2)=10] - │ │ ├── cost: 1094.81 + │ │ ├── cost: 1105.61 │ │ ├── key: (1) │ │ ├── fd: (1)-->(2) │ │ ├── prune: (1,2) @@ -1102,7 +1102,7 @@ anti-join (lookup geo_table) ├── second join in paired joiner ├── immutable ├── stats: [rows=990] - ├── cost: 112694.84 + ├── cost: 112705.64 ├── key: (1) ├── fd: (1)-->(2) ├── prune: (1) @@ -1112,13 +1112,13 @@ anti-join (lookup geo_table) │ ├── inverted-expr │ │ └── st_intersects(geo_table2.geom:2, geo_table.geom:12) │ ├── stats: [rows=10000, distinct(1)=1000, null(1)=0, distinct(11)=999.956829, null(11)=0] - │ ├── cost: 41994.82 + │ ├── cost: 42005.62 │ ├── key: (1,11) │ ├── fd: (1)-->(2), (11)-->(16) │ ├── scan geo_table2 │ │ ├── columns: geo_table2.k:1 geo_table2.geom:2 │ │ ├── stats: [rows=1000, distinct(1)=1000, null(1)=0] - │ │ ├── cost: 1094.81 + │ │ ├── cost: 1105.61 │ │ ├── key: (1) │ │ ├── fd: (1)-->(2) │ │ ├── prune: (1,2) diff --git a/pkg/sql/opt/exec/execbuilder/testdata/stats b/pkg/sql/opt/exec/execbuilder/testdata/stats index a7a3f39e332f..d259e02ed8ad 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/stats +++ b/pkg/sql/opt/exec/execbuilder/testdata/stats @@ -220,13 +220,13 @@ distinct-on ├── grouping columns: u:1 v:2 ├── internal-ordering: +1 ├── stats: [rows=20.0617284, distinct(1,2)=20.0617284, null(1,2)=0] - ├── cost: 41.7306173 + ├── cost: 52.7306173 ├── key: (1,2) └── scan uv@uv_u_idx ├── columns: u:1 v:2 ├── constraint: /1/3: (/NULL - /29] ├── stats: [rows=33.3333333, distinct(1)=6.66666667, null(1)=0, distinct(1,2)=20.0617284, null(1,2)=0] - ├── cost: 40.6766667 + ├── cost: 51.6766667 ├── ordering: +1 ├── prune: (2) └── interesting orderings: (+1) (+2) @@ -242,13 +242,13 @@ distinct-on ├── grouping columns: u:1 v:2 ├── internal-ordering: +1 ├── stats: [rows=33.3333333, distinct(1,2)=33.3333333, null(1,2)=0] - ├── cost: 41.8633333 + ├── cost: 52.8633333 ├── key: (1,2) └── scan uv@uv_u_idx ├── columns: u:1 v:2 ├── constraint: /1/3: (/NULL - /29] ├── stats: [rows=33.3333333, distinct(1)=6.66666667, null(1)=0, distinct(1,2)=33.3333333, null(1,2)=0] - ├── cost: 40.6766667 + ├── cost: 51.6766667 ├── ordering: +1 ├── prune: (2) └── interesting orderings: (+1) (+2) @@ -264,7 +264,7 @@ distinct-on ├── grouping columns: u:1 v:2 ├── internal-ordering: +1 ├── stats: [rows=100, distinct(1,2)=100, null(1,2)=0] - ├── cost: 117.53 + ├── cost: 128.53 ├── key: (1,2) └── scan uv@uv_u_idx ├── columns: u:1 v:2 @@ -272,7 +272,7 @@ distinct-on ├── stats: [rows=100, distinct(1)=20, null(1)=0, distinct(1,2)=100, null(1,2)=0] │ histogram(1)= 0 50 0 20 8 5 12 5 │ <--- 1 --- 2 --- 10 ---- 20 - ├── cost: 114.01 + ├── cost: 125.01 ├── ordering: +1 ├── prune: (2) └── interesting orderings: (+1) (+2) @@ -288,7 +288,7 @@ distinct-on ├── grouping columns: u:1 v:2 ├── internal-ordering: +1 ├── stats: [rows=25, distinct(1,2)=25, null(1,2)=0] - ├── cost: 116.78 + ├── cost: 127.78 ├── key: (1,2) └── scan uv@uv_u_idx ├── columns: u:1 v:2 @@ -296,7 +296,7 @@ distinct-on ├── stats: [rows=100, distinct(1)=20, null(1)=0, distinct(1,2)=25, null(1,2)=0] │ histogram(1)= 0 50 0 20 8 5 12 5 │ <--- 1 --- 2 --- 10 ---- 20 - ├── cost: 114.01 + ├── cost: 125.01 ├── ordering: +1 ├── prune: (2) └── interesting orderings: (+1) (+2) diff --git a/pkg/sql/opt/memo/testdata/format b/pkg/sql/opt/memo/testdata/format index 1f4fea60efd0..603af5d455c1 100644 --- a/pkg/sql/opt/memo/testdata/format +++ b/pkg/sql/opt/memo/testdata/format @@ -9,7 +9,7 @@ project ├── columns: "?column?":6(int) min:5(int!null) [hidden: t.public.t.a:1(int)] ├── immutable ├── stats: [rows=98.1771622] - ├── cost: 1114.43579 + ├── cost: 1125.03579 ├── key: (1) ├── fd: (1)-->(5,6) ├── ordering: +1 @@ -18,7 +18,7 @@ project │ ├── columns: t.public.t.a:1(int) min:5(int!null) │ ├── immutable │ ├── stats: [rows=98.1771622, distinct(1)=98.1771622, null(1)=1] - │ ├── cost: 1112.46224 + │ ├── cost: 1123.06224 │ ├── key: (1) │ ├── fd: (1)-->(5) │ ├── ordering: +1 @@ -28,7 +28,7 @@ project │ ├── grouping columns: t.public.t.a:1(int) │ ├── immutable │ ├── stats: [rows=98.1771622, distinct(1)=98.1771622, null(1)=1] - │ ├── cost: 1095.53177 + │ ├── cost: 1106.13177 │ ├── key: (1) │ ├── fd: (1)-->(5) │ ├── prune: (5) @@ -36,14 +36,14 @@ project │ │ ├── columns: t.public.t.a:1(int) t.public.t.b:2(int!null) t.public.t.k:3(int!null) │ │ ├── immutable │ │ ├── stats: [rows=330, distinct(1)=98.1771622, null(1)=3.3, distinct(2)=100, null(2)=0] - │ │ ├── cost: 1084.63 + │ │ ├── cost: 1095.23 │ │ ├── key: (3) │ │ ├── fd: (3)-->(1,2) │ │ ├── interesting orderings: (+3) │ │ ├── scan t.public.t │ │ │ ├── columns: t.public.t.a:1(int) t.public.t.b:2(int) t.public.t.k:3(int!null) │ │ │ ├── stats: [rows=1000, distinct(1)=100, null(1)=10, distinct(2)=100, null(2)=10] - │ │ │ ├── cost: 1074.61 + │ │ │ ├── cost: 1085.21 │ │ │ ├── key: (3) │ │ │ ├── fd: (3)-->(1,2) │ │ │ ├── prune: (1-3) @@ -68,26 +68,26 @@ SELECT a + 1, min(b) FROM t WHERE k + a > b GROUP BY a ORDER BY a project ├── columns: "?column?":6(int) min:5(int!null) [hidden: t.public.t.a:1(int)] ├── stats: [rows=98.1771622] - ├── cost: 1114.43579 + ├── cost: 1125.03579 ├── ordering: +1 ├── sort │ ├── columns: t.public.t.a:1(int) min:5(int!null) │ ├── stats: [rows=98.1771622, distinct(1)=98.1771622, null(1)=1] - │ ├── cost: 1112.46224 + │ ├── cost: 1123.06224 │ ├── ordering: +1 │ └── group-by │ ├── columns: t.public.t.a:1(int) min:5(int!null) │ ├── grouping columns: t.public.t.a:1(int) │ ├── stats: [rows=98.1771622, distinct(1)=98.1771622, null(1)=1] - │ ├── cost: 1095.53177 + │ ├── cost: 1106.13177 │ ├── select │ │ ├── columns: t.public.t.a:1(int) t.public.t.b:2(int!null) t.public.t.k:3(int!null) │ │ ├── stats: [rows=330, distinct(1)=98.1771622, null(1)=3.3, distinct(2)=100, null(2)=0] - │ │ ├── cost: 1084.63 + │ │ ├── cost: 1095.23 │ │ ├── scan t.public.t │ │ │ ├── columns: t.public.t.a:1(int) t.public.t.b:2(int) t.public.t.k:3(int!null) │ │ │ ├── stats: [rows=1000, distinct(1)=100, null(1)=10, distinct(2)=100, null(2)=10] - │ │ │ └── cost: 1074.61 + │ │ │ └── cost: 1085.21 │ │ └── filters │ │ └── lt [type=bool] │ │ ├── variable: t.public.t.b:2 [type=int] @@ -283,31 +283,31 @@ SELECT a + 1, min(b) FROM t WHERE k + a > b GROUP BY a ORDER BY a ---- project ├── stats: [rows=98.1771622] - ├── cost: 1114.43579 + ├── cost: 1125.03579 ├── key: (1) ├── fd: (1)-->(5,6) ├── prune: (1,5,6) ├── sort │ ├── stats: [rows=98.1771622, distinct(1)=98.1771622, null(1)=1] - │ ├── cost: 1112.46224 + │ ├── cost: 1123.06224 │ ├── key: (1) │ ├── fd: (1)-->(5) │ ├── prune: (5) │ └── group-by │ ├── stats: [rows=98.1771622, distinct(1)=98.1771622, null(1)=1] - │ ├── cost: 1095.53177 + │ ├── cost: 1106.13177 │ ├── key: (1) │ ├── fd: (1)-->(5) │ ├── prune: (5) │ ├── select │ │ ├── stats: [rows=330, distinct(1)=98.1771622, null(1)=3.3, distinct(2)=100, null(2)=0] - │ │ ├── cost: 1084.63 + │ │ ├── cost: 1095.23 │ │ ├── key: (3) │ │ ├── fd: (3)-->(1,2) │ │ ├── interesting orderings: (+3) │ │ ├── scan t.public.t │ │ │ ├── stats: [rows=1000, distinct(1)=100, null(1)=10, distinct(2)=100, null(2)=10] - │ │ │ ├── cost: 1074.61 + │ │ │ ├── cost: 1085.21 │ │ │ ├── key: (3) │ │ │ ├── fd: (3)-->(1,2) │ │ │ ├── prune: (1-3) diff --git a/pkg/sql/opt/memo/testdata/memo b/pkg/sql/opt/memo/testdata/memo index e0a346a99d5f..6ec1a0f32bd5 100644 --- a/pkg/sql/opt/memo/testdata/memo +++ b/pkg/sql/opt/memo/testdata/memo @@ -132,44 +132,44 @@ memo (optimized, ~21KB, required=[presentation: y:2,x:4,c:8] [ordering: +2]) ├── G1: (project G2 G3 y x) │ ├── [presentation: y:2,x:4,c:8] [ordering: +2] │ │ ├── best: (project G2="[ordering: +2]" G3 y x) - │ │ └── cost: 1744.65 + │ │ └── cost: 1755.05 │ └── [] │ ├── best: (project G2 G3 y x) - │ └── cost: 1744.65 + │ └── cost: 1755.05 ├── G2: (limit G4 G5 ordering=+2) │ ├── [ordering: +2] │ │ ├── best: (limit G4="[ordering: +2] [limit hint: 10.00]" G5 ordering=+2) - │ │ └── cost: 1744.44 + │ │ └── cost: 1754.84 │ └── [] │ ├── best: (limit G4="[ordering: +2] [limit hint: 10.00]" G5 ordering=+2) - │ └── cost: 1744.44 + │ └── cost: 1754.84 ├── G3: (projections G6) ├── G4: (inner-join G7 G8 G9) (inner-join G7 G8 G9) (inner-join G8 G7 G9) (lookup-join G7 G10 b,keyCols=[7],outCols=(2,4,7)) (lookup-join G7 G10 b,keyCols=[7],outCols=(2,4,7)) (merge-join G8 G7 G10 inner-join,+4,+7) │ ├── [ordering: +2] [limit hint: 10.00] │ │ ├── best: (lookup-join G7="[ordering: +2] [limit hint: 100.00]" G10 b,keyCols=[7],outCols=(2,4,7)) - │ │ └── cost: 1744.33 + │ │ └── cost: 1754.73 │ └── [] │ ├── best: (inner-join G8 G7 G9) - │ └── cost: 2137.10 + │ └── cost: 2157.80 ├── G5: (const 10) ├── G6: (plus G11 G12) ├── G7: (project G13 G14 y) │ ├── [ordering: +2] [limit hint: 100.00] │ │ ├── best: (sort G7) - │ │ └── cost: 1140.32 + │ │ └── cost: 1150.72 │ ├── [ordering: +7] │ │ ├── best: (sort G7) - │ │ └── cost: 1140.32 + │ │ └── cost: 1150.72 │ └── [] │ ├── best: (project G13 G14 y) - │ └── cost: 1071.11 + │ └── cost: 1081.51 ├── G8: (scan b,cols=(4)) │ ├── [ordering: +4] │ │ ├── best: (scan b,cols=(4)) - │ │ └── cost: 1044.31 + │ │ └── cost: 1054.61 │ └── [] │ ├── best: (scan b,cols=(4)) - │ └── cost: 1044.31 + │ └── cost: 1054.61 ├── G9: (filters G15) ├── G10: (filters) ├── G11: (variable y) @@ -177,19 +177,19 @@ memo (optimized, ~21KB, required=[presentation: y:2,x:4,c:8] [ordering: +2]) ├── G13: (select G16 G17) │ ├── [ordering: +2] [limit hint: 100.00] │ │ ├── best: (sort G13) - │ │ └── cost: 1133.65 + │ │ └── cost: 1144.05 │ └── [] │ ├── best: (select G16 G17) - │ └── cost: 1064.43 + │ └── cost: 1074.83 ├── G14: (projections G18) ├── G15: (eq G19 G20) ├── G16: (scan a,cols=(1,2)) │ ├── [ordering: +2] [limit hint: 300.00] │ │ ├── best: (sort G16) - │ │ └── cost: 1293.74 + │ │ └── cost: 1304.14 │ └── [] │ ├── best: (scan a,cols=(1,2)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G17: (filters G21) ├── G18: (cast G22 STRING) ├── G19: (variable column7) @@ -207,16 +207,16 @@ memo (optimized, ~6KB, required=[presentation: a:4,b:5,c:6,d:7]) ├── G1: (project G2 G3) │ └── [presentation: a:4,b:5,c:6,d:7] │ ├── best: (project G2 G3) - │ └── cost: 1064.62 + │ └── cost: 1075.02 ├── G2: (select G4 G5) │ └── [] │ ├── best: (select G4 G5) - │ └── cost: 1064.44 + │ └── cost: 1074.84 ├── G3: (projections G6 G7 G8 G9) ├── G4: (scan b,cols=(1,2)) │ └── [] │ ├── best: (scan b,cols=(1,2)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G5: (filters G10 G11) ├── G6: (const 1) ├── G7: (plus G12 G13) @@ -251,7 +251,7 @@ memo (optimized, ~7KB, required=[presentation: x:1]) ├── G4: (scan a,cols=(1,2)) │ └── [] │ ├── best: (scan a,cols=(1,2)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G5: (filters G8 G9) ├── G6: (scan a,cols=(1,2),constrained) │ └── [] @@ -272,19 +272,19 @@ memo (optimized, ~7KB, required=[presentation: x:9,y:10]) ├── G1: (union G2 G3) │ └── [presentation: x:9,y:10] │ ├── best: (union G2 G3) - │ └── cost: 2178.84 + │ └── cost: 2199.64 ├── G2: (scan a,cols=(1,2)) │ └── [] │ ├── best: (scan a,cols=(1,2)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G3: (project G4 G5) │ └── [] │ ├── best: (project G4 G5) - │ └── cost: 1084.42 + │ └── cost: 1094.82 ├── G4: (scan a,cols=(4,5)) │ └── [] │ ├── best: (scan a,cols=(4,5)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G5: (projections G6 G7) ├── G6: (plus G8 G9) ├── G7: (plus G10 G9) @@ -299,11 +299,11 @@ memo (optimized, ~4KB, required=[presentation: array_agg:4]) ├── G1: (scalar-group-by G2 G3 cols=()) │ └── [presentation: array_agg:4] │ ├── best: (scalar-group-by G2 G3 cols=()) - │ └── cost: 1054.34 + │ └── cost: 1064.64 ├── G2: (scan a,cols=(1)) │ └── [] │ ├── best: (scan a,cols=(1)) - │ └── cost: 1044.31 + │ └── cost: 1054.61 ├── G3: (aggregations G4) ├── G4: (array-agg G5) └── G5: (variable x) @@ -315,16 +315,16 @@ memo (optimized, ~4KB, required=[presentation: array_agg:4]) ├── G1: (project G2 G3 array_agg) │ └── [presentation: array_agg:4] │ ├── best: (project G2 G3 array_agg) - │ └── cost: 1086.44 + │ └── cost: 1096.84 ├── G2: (group-by G4 G5 cols=(2)) │ └── [] │ ├── best: (group-by G4 G5 cols=(2)) - │ └── cost: 1085.43 + │ └── cost: 1095.83 ├── G3: (projections) ├── G4: (scan a,cols=(1,2)) │ └── [] │ ├── best: (scan a,cols=(1,2)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G5: (aggregations G6) ├── G6: (array-agg G7) └── G7: (variable x) @@ -336,14 +336,14 @@ memo (optimized, ~3KB, required=[presentation: array_agg:4]) ├── G1: (scalar-group-by G2 G3 cols=(),ordering=+2) │ └── [presentation: array_agg:4] │ ├── best: (scalar-group-by G2="[ordering: +2]" G3 cols=(),ordering=+2) - │ └── cost: 1303.77 + │ └── cost: 1314.17 ├── G2: (scan a,cols=(1,2)) │ ├── [ordering: +2] │ │ ├── best: (sort G2) - │ │ └── cost: 1293.74 + │ │ └── cost: 1304.14 │ └── [] │ ├── best: (scan a,cols=(1,2)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G3: (aggregations G4) ├── G4: (array-agg G5) └── G5: (variable x) diff --git a/pkg/sql/opt/memo/testdata/stats/inverted-geo b/pkg/sql/opt/memo/testdata/stats/inverted-geo index b57f517bbb38..7f41b629e6b7 100644 --- a/pkg/sql/opt/memo/testdata/stats/inverted-geo +++ b/pkg/sql/opt/memo/testdata/stats/inverted-geo @@ -95,45 +95,45 @@ memo (optimized, ~11KB, required=[presentation: i:1]) ├── G1: (project G2 G3 i) │ └── [presentation: i:1] │ ├── best: (project G2 G3 i) - │ └── cost: 2642.30 + │ └── cost: 2652.80 ├── G2: (limit G4 G5 ordering=+1) │ └── [] │ ├── best: (limit G4="[ordering: +1] [limit hint: 1.00]" G5 ordering=+1) - │ └── cost: 2642.28 + │ └── cost: 2652.78 ├── G3: (projections) ├── G4: (select G6 G7) (select G8 G7) │ ├── [ordering: +1] [limit hint: 1.00] │ │ ├── best: (select G6="[ordering: +1] [limit hint: 9.00]" G7) - │ │ └── cost: 2642.26 + │ │ └── cost: 2652.76 │ └── [] │ ├── best: (select G6 G7) - │ └── cost: 4134.53 + │ └── cost: 4145.03 ├── G5: (const 1) ├── G6: (scan t,cols=(1,2)) │ ├── [ordering: +1] [limit hint: 9.00] │ │ ├── best: (sort G6) - │ │ └── cost: 2633.15 + │ │ └── cost: 2643.65 │ └── [] │ ├── best: (scan t,cols=(1,2)) - │ └── cost: 2114.51 + │ └── cost: 2125.01 ├── G7: (filters G9) ├── G8: (index-join G10 t,cols=(1,2)) │ ├── [ordering: +1] [limit hint: 13.50] │ │ ├── best: (sort G8) - │ │ └── cost: 22155.08 + │ │ └── cost: 22165.48 │ └── [] │ ├── best: (index-join G10 t,cols=(1,2)) - │ └── cost: 21342.03 + │ └── cost: 21352.43 ├── G9: (function G11 st_intersects) ├── G10: (inverted-filter G12 g_inverted_key) │ └── [] │ ├── best: (inverted-filter G12 g_inverted_key) - │ └── cost: 3162.02 + │ └── cost: 3172.42 ├── G11: (scalar-list G13 G14) ├── G12: (scan t@secondary,cols=(3,5),constrained inverted) │ └── [] │ ├── best: (scan t@secondary,cols=(3,5),constrained inverted) - │ └── cost: 3132.01 + │ └── cost: 3142.41 ├── G13: (const '010200000002000000000000000000E03F000000000000E03F666666666666E63F666666666666E63F') └── G14: (variable g) @@ -199,45 +199,45 @@ memo (optimized, ~11KB, required=[presentation: i:1]) ├── G1: (project G2 G3 i) │ └── [presentation: i:1] │ ├── best: (project G2 G3 i) - │ └── cost: 4.10 + │ └── cost: 14.50 ├── G2: (limit G4 G5 ordering=+1) │ └── [] │ ├── best: (limit G4="[ordering: +1] [limit hint: 1.00]" G5 ordering=+1) - │ └── cost: 4.08 + │ └── cost: 14.48 ├── G3: (projections) ├── G4: (select G6 G7) (select G8 G7) │ ├── [ordering: +1] [limit hint: 1.00] │ │ ├── best: (select G8="[ordering: +1] [limit hint: 0.00]" G7) - │ │ └── cost: 4.06 + │ │ └── cost: 14.46 │ └── [] │ ├── best: (select G8 G7) - │ └── cost: 4.05 + │ └── cost: 14.45 ├── G5: (const 1) ├── G6: (scan t,cols=(1,2)) │ ├── [ordering: +1] [limit hint: 9.00] │ │ ├── best: (sort G6) - │ │ └── cost: 2633.15 + │ │ └── cost: 2643.65 │ └── [] │ ├── best: (scan t,cols=(1,2)) - │ └── cost: 2114.51 + │ └── cost: 2125.01 ├── G7: (filters G9) ├── G8: (index-join G10 t,cols=(1,2)) │ ├── [ordering: +1] [limit hint: 0.00] │ │ ├── best: (sort G8) - │ │ └── cost: 4.04 + │ │ └── cost: 14.44 │ └── [] │ ├── best: (index-join G10 t,cols=(1,2)) - │ └── cost: 4.03 + │ └── cost: 14.43 ├── G9: (function G11 st_intersects) ├── G10: (inverted-filter G12 g_inverted_key) │ └── [] │ ├── best: (inverted-filter G12 g_inverted_key) - │ └── cost: 4.02 + │ └── cost: 14.42 ├── G11: (scalar-list G13 G14) ├── G12: (scan t@secondary,cols=(3,5),constrained inverted) │ └── [] │ ├── best: (scan t@secondary,cols=(3,5),constrained inverted) - │ └── cost: 4.01 + │ └── cost: 14.41 ├── G13: (const '010200000002000000000000000000594000000000000059400000000000C062400000000000C06240') └── G14: (variable g) @@ -307,11 +307,11 @@ memo (optimized, ~4KB, required=[presentation: i:1,g:2]) ├── G1: (select G2 G3) │ └── [presentation: i:1,g:2] │ ├── best: (select G2 G3) - │ └── cost: 2134.53 + │ └── cost: 2145.03 ├── G2: (scan t,cols=(1,2)) │ └── [] │ ├── best: (scan t,cols=(1,2)) - │ └── cost: 2114.51 + │ └── cost: 2125.01 ├── G3: (filters G4) ├── G4: (or G5 G6) ├── G5: (is G7 G8) diff --git a/pkg/sql/opt/memo/testdata/stats/join b/pkg/sql/opt/memo/testdata/stats/join index 3b0ae2622faf..184b98a26e25 100644 --- a/pkg/sql/opt/memo/testdata/stats/join +++ b/pkg/sql/opt/memo/testdata/stats/join @@ -1361,14 +1361,14 @@ inner-join (lookup t.public.def) ├── columns: t.public.abc.a:1(int!null) t.public.abc.b:2(int!null) t.public.abc.c:3(int) t.public.def.d:5(int!null) t.public.def.e:6(int!null) t.public.def.f:7(int) ├── key columns: [1 2] = [5 6] ├── stats: [rows=0.01, distinct(1)=0.01, null(1)=0, distinct(2)=0.01, null(2)=0, distinct(3)=0.00999500175, null(3)=0.0001, distinct(5)=0.01, null(5)=0, distinct(6)=0.01, null(6)=0, distinct(7)=0.00999995009, null(7)=0.0001, distinct(6,7)=0.00999999509, null(6,7)=0, distinct(1-3)=0.0099995001, null(1-3)=0] - ├── cost: 2120.6407 + ├── cost: 2131.2407 ├── key: (5,6) ├── fd: (1,2)-->(3), (5,6)-->(7), (1)==(5), (5)==(1), (2)==(6), (6)==(2) ├── interesting orderings: (+1,+2) ├── scan t.public.abc │ ├── columns: t.public.abc.a:1(int!null) t.public.abc.b:2(int!null) t.public.abc.c:3(int) │ ├── stats: [rows=100, distinct(1)=100, null(1)=0, distinct(2)=10, null(2)=0, distinct(3)=10, null(3)=1, distinct(1-3)=100, null(1-3)=0] - │ ├── cost: 120.61 + │ ├── cost: 131.21 │ ├── key: (1,2) │ ├── fd: (1,2)-->(3) │ ├── prune: (1-3) @@ -1389,14 +1389,14 @@ semi-join (lookup t.public.def) ├── columns: t.public.abc.a:1(int!null) t.public.abc.b:2(int!null) t.public.abc.c:3(int) ├── key columns: [1 2] = [5 6] ├── stats: [rows=100, distinct(1)=100, null(1)=0, distinct(2)=10, null(2)=0, distinct(3)=10, null(3)=1, distinct(6)=1, null(6)=0, distinct(7)=1, null(7)=0, distinct(6,7)=1, null(6,7)=0, distinct(1-3)=100, null(1-3)=0] - ├── cost: 2120.6406 + ├── cost: 2131.2406 ├── key: (1,2) ├── fd: (1,2)-->(3) ├── interesting orderings: (+1,+2) ├── scan t.public.abc │ ├── columns: t.public.abc.a:1(int!null) t.public.abc.b:2(int!null) t.public.abc.c:3(int) │ ├── stats: [rows=100, distinct(1)=100, null(1)=0, distinct(2)=10, null(2)=0, distinct(3)=10, null(3)=1, distinct(1-3)=100, null(1-3)=0] - │ ├── cost: 120.61 + │ ├── cost: 131.21 │ ├── key: (1,2) │ ├── fd: (1,2)-->(3) │ ├── prune: (1-3) @@ -1414,14 +1414,14 @@ anti-join (lookup t.public.def) ├── columns: t.public.abc.a:1(int!null) t.public.abc.b:2(int!null) t.public.abc.c:3(int) ├── key columns: [1 2] = [5 6] ├── stats: [rows=1e-10, distinct(1)=1e-10, null(1)=0, distinct(2)=1e-10, null(2)=0, distinct(3)=1e-10, null(3)=1e-10, distinct(6)=1e-10, null(6)=0, distinct(7)=1e-10, null(7)=0, distinct(6,7)=1e-10, null(6,7)=0, distinct(1-3)=1e-10, null(1-3)=0] - ├── cost: 2120.6406 + ├── cost: 2131.2406 ├── key: (1,2) ├── fd: (1,2)-->(3) ├── interesting orderings: (+1,+2) ├── scan t.public.abc │ ├── columns: t.public.abc.a:1(int!null) t.public.abc.b:2(int!null) t.public.abc.c:3(int) │ ├── stats: [rows=100, distinct(1)=100, null(1)=0, distinct(2)=10, null(2)=0, distinct(3)=10, null(3)=1, distinct(1-3)=100, null(1-3)=0] - │ ├── cost: 120.61 + │ ├── cost: 131.21 │ ├── key: (1,2) │ ├── fd: (1,2)-->(3) │ ├── prune: (1-3) @@ -1439,14 +1439,14 @@ semi-join (lookup t.public.def) ├── columns: t.public.abc.a:1(int!null) t.public.abc.b:2(int!null) t.public.abc.c:3(int) ├── key columns: [1 2] = [5 6] ├── stats: [rows=0, distinct(1)=0, null(1)=0, distinct(2)=0, null(2)=0, distinct(3)=0, null(3)=0, distinct(6)=0, null(6)=0, distinct(7)=0, null(7)=0, distinct(6,7)=0, null(6,7)=0, distinct(1-3)=0, null(1-3)=0] - ├── cost: 2120.6506 + ├── cost: 2131.2506 ├── key: (1,2) ├── fd: (1,2)-->(3) ├── interesting orderings: (+1,+2) ├── scan t.public.abc │ ├── columns: t.public.abc.a:1(int!null) t.public.abc.b:2(int!null) t.public.abc.c:3(int) │ ├── stats: [rows=100, distinct(1)=100, null(1)=0, distinct(2)=10, null(2)=0, distinct(3)=10, null(3)=1, distinct(1-3)=100, null(1-3)=0] - │ ├── cost: 120.61 + │ ├── cost: 131.21 │ ├── key: (1,2) │ ├── fd: (1,2)-->(3) │ ├── prune: (1-3) @@ -1465,14 +1465,14 @@ anti-join (lookup t.public.def) ├── columns: t.public.abc.a:1(int!null) t.public.abc.b:2(int!null) t.public.abc.c:3(int) ├── key columns: [1 2] = [5 6] ├── stats: [rows=100, distinct(1)=100, null(1)=0, distinct(2)=10, null(2)=0, distinct(3)=10, null(3)=1, distinct(6)=1, null(6)=0, distinct(7)=1, null(7)=0, distinct(6,7)=1, null(6,7)=0, distinct(1-3)=100, null(1-3)=0] - ├── cost: 2120.6506 + ├── cost: 2131.2506 ├── key: (1,2) ├── fd: (1,2)-->(3) ├── interesting orderings: (+1,+2) ├── scan t.public.abc │ ├── columns: t.public.abc.a:1(int!null) t.public.abc.b:2(int!null) t.public.abc.c:3(int) │ ├── stats: [rows=100, distinct(1)=100, null(1)=0, distinct(2)=10, null(2)=0, distinct(3)=10, null(3)=1, distinct(1-3)=100, null(1-3)=0] - │ ├── cost: 120.61 + │ ├── cost: 131.21 │ ├── key: (1,2) │ ├── fd: (1,2)-->(3) │ ├── prune: (1-3) diff --git a/pkg/sql/opt/norm/testdata/rules/combo b/pkg/sql/opt/norm/testdata/rules/combo index 922215d5666a..97a76394b4b4 100644 --- a/pkg/sql/opt/norm/testdata/rules/combo +++ b/pkg/sql/opt/norm/testdata/rules/combo @@ -21,7 +21,7 @@ SELECT s FROM a INNER JOIN xy ON a.k=xy.x AND i+1=10 ---- ================================================================================ Initial expression - Cost: 15552.98 + Cost: 15574.58 ================================================================================ project ├── columns: s:4 @@ -43,7 +43,7 @@ Initial expression └── (k:1 = x:7) AND ((i:2 + 1) = 10) [outer=(1,2,7), immutable, constraints=(/1: (/NULL - ]; /7: (/NULL - ])] ================================================================================ NormalizeCmpPlusConst - Cost: 15519.65 + Cost: 15541.25 ================================================================================ project ├── columns: s:4 @@ -67,7 +67,7 @@ NormalizeCmpPlusConst + └── (k:1 = x:7) AND (i:2 = (10 - 1)) [outer=(1,2,7), immutable, constraints=(/1: (/NULL - ]; /2: (/NULL - ]; /7: (/NULL - ])] ================================================================================ FoldBinary - Cost: 12252.98 + Cost: 12274.58 ================================================================================ project ├── columns: s:4 @@ -91,7 +91,7 @@ FoldBinary + └── (k:1 = x:7) AND (i:2 = 9) [outer=(1,2,7), constraints=(/1: (/NULL - ]; /2: [/9 - /9]; /7: (/NULL - ]), fd=()-->(2)] ================================================================================ SimplifyJoinFilters - Cost: 2229.76 + Cost: 2251.36 ================================================================================ project ├── columns: s:4 @@ -117,7 +117,7 @@ SimplifyJoinFilters + └── i:2 = 9 [outer=(2), constraints=(/2: [/9 - /9]; tight), fd=()-->(2)] ================================================================================ PushFilterIntoJoinLeft - Cost: 2217.50 + Cost: 2239.10 ================================================================================ project ├── columns: s:4 @@ -149,7 +149,7 @@ PushFilterIntoJoinLeft + └── k:1 = x:7 [outer=(1,7), constraints=(/1: (/NULL - ]; /7: (/NULL - ]), fd=(1)==(7), (7)==(1)] ================================================================================ PruneJoinLeftCols - Cost: 2217.61 + Cost: 2239.21 ================================================================================ project ├── columns: s:4 @@ -191,7 +191,7 @@ PruneJoinLeftCols └── k:1 = x:7 [outer=(1,7), constraints=(/1: (/NULL - ]; /7: (/NULL - ]), fd=(1)==(7), (7)==(1)] ================================================================================ PruneSelectCols - Cost: 2187.31 + Cost: 2208.61 ================================================================================ project ├── columns: s:4 @@ -226,7 +226,7 @@ PruneSelectCols └── k:1 = x:7 [outer=(1,7), constraints=(/1: (/NULL - ]; /7: (/NULL - ]), fd=(1)==(7), (7)==(1)] ================================================================================ EliminateProject - Cost: 2187.20 + Cost: 2208.50 ================================================================================ project ├── columns: s:4 @@ -264,7 +264,7 @@ EliminateProject └── k:1 = x:7 [outer=(1,7), constraints=(/1: (/NULL - ]; /7: (/NULL - ]), fd=(1)==(7), (7)==(1)] ================================================================================ PruneJoinRightCols - Cost: 2167.00 + Cost: 2188.10 ================================================================================ project ├── columns: s:4 @@ -310,7 +310,7 @@ GenerateIndexScans (no changes) -------------------------------------------------------------------------------- ================================================================================ ReorderJoins - Cost: 2162.05 + Cost: 2183.15 ================================================================================ project ├── columns: s:4 @@ -339,7 +339,7 @@ ReorderJoins └── k:1 = x:7 [outer=(1,7), constraints=(/1: (/NULL - ]; /7: (/NULL - ]), fd=(1)==(7), (7)==(1)] ================================================================================ GenerateMergeJoins - Cost: 2159.46 + Cost: 2180.56 ================================================================================ project ├── columns: s:4 @@ -376,7 +376,7 @@ GenerateMergeJoins + └── filters (true) ================================================================================ GenerateLookupJoins - Cost: 1165.35 + Cost: 1176.15 ================================================================================ project ├── columns: s:4 @@ -510,7 +510,7 @@ GenerateLookupJoinsWithFilter (higher cost) + └── i:2 = 9 [outer=(2), constraints=(/2: [/9 - /9]; tight), fd=()-->(2)] ================================================================================ Final best expression - Cost: 1165.35 + Cost: 1176.15 ================================================================================ project ├── columns: s:4 @@ -538,7 +538,7 @@ SELECT s, k FROM a WHERE s='foo' AND f>100 ---- ================================================================================ Initial expression - Cost: 1135.23 + Cost: 1146.33 ================================================================================ project ├── columns: s:4!null k:1!null @@ -556,7 +556,7 @@ Initial expression └── (s:4 = 'foo') AND (f:3 > 100.0) [outer=(3,4), constraints=(/3: [/100.00000000000001 - ]; /4: [/'foo' - /'foo']; tight), fd=()-->(4)] ================================================================================ SimplifySelectFilters - Cost: 1135.24 + Cost: 1146.34 ================================================================================ project ├── columns: s:4!null k:1!null @@ -576,7 +576,7 @@ SimplifySelectFilters + └── f:3 > 100.0 [outer=(3), constraints=(/3: [/100.00000000000001 - ]; tight)] ================================================================================ PruneSelectCols - Cost: 1104.94 + Cost: 1115.74 ================================================================================ project ├── columns: s:4!null k:1!null @@ -599,7 +599,7 @@ PruneSelectCols └── f:3 > 100.0 [outer=(3), constraints=(/3: [/100.00000000000001 - ]; tight)] ================================================================================ GenerateIndexScans - Cost: 1094.84 + Cost: 1105.54 ================================================================================ project ├── columns: s:4!null k:1!null @@ -622,7 +622,7 @@ GeneratePartialIndexScans (no changes) -------------------------------------------------------------------------------- ================================================================================ GenerateConstrainedScans - Cost: 14.10 + Cost: 24.80 ================================================================================ project ├── columns: s:4!null k:1!null @@ -647,7 +647,7 @@ GenerateZigzagJoins (no changes) -------------------------------------------------------------------------------- ================================================================================ Final best expression - Cost: 14.10 + Cost: 24.80 ================================================================================ project ├── columns: s:4!null k:1!null @@ -665,7 +665,7 @@ SELECT * FROM a WHERE EXISTS(SELECT * FROM xy WHERE y=i) ---- ================================================================================ Initial expression - Cost: 2222.91 + Cost: 2244.51 ================================================================================ project ├── columns: k:1!null i:2 f:3 s:4 j:5 @@ -699,7 +699,7 @@ Initial expression └── y:8 = i:2 [outer=(2,8), constraints=(/2: (/NULL - ]; /8: (/NULL - ]), fd=(2)==(8), (8)==(2)] ================================================================================ PruneSelectCols - Cost: 2212.81 + Cost: 2234.31 ================================================================================ project ├── columns: k:1!null i:2 f:3 s:4 j:5 @@ -737,7 +737,7 @@ PruneSelectCols └── y:8 = i:2 [outer=(2,8), constraints=(/2: (/NULL - ]; /8: (/NULL - ]), fd=(2)==(8), (8)==(2)] ================================================================================ EliminateProject - Cost: 2202.90 + Cost: 2224.40 ================================================================================ project ├── columns: k:1!null i:2 f:3 s:4 j:5 @@ -778,7 +778,7 @@ EliminateProject + └── y:8 = i:2 [outer=(2,8), constraints=(/2: (/NULL - ]; /8: (/NULL - ]), fd=(2)==(8), (8)==(2)] ================================================================================ HoistSelectExists - Cost: 12139.40 + Cost: 12160.90 ================================================================================ project ├── columns: k:1!null i:2 f:3 s:4 j:5 @@ -826,7 +826,7 @@ HoistSelectExists + └── filters (true) ================================================================================ TryDecorrelateSelect - Cost: 2329.36 + Cost: 2350.86 ================================================================================ project - ├── columns: k:1!null i:2 f:3 s:4 j:5 @@ -867,7 +867,7 @@ TryDecorrelateSelect └── filters (true) ================================================================================ DecorrelateJoin - Cost: 2327.57 + Cost: 2349.07 ================================================================================ project - ├── columns: k:1!null i:2!null f:3 s:4 j:5 @@ -898,7 +898,7 @@ DecorrelateJoin └── filters (true) ================================================================================ PruneSemiAntiJoinRightCols - Cost: 2317.47 + Cost: 2338.87 ================================================================================ project ├── columns: k:1!null i:2 f:3 s:4 j:5 @@ -926,7 +926,7 @@ PruneSemiAntiJoinRightCols └── filters (true) ================================================================================ EliminateSelect - Cost: 2307.46 + Cost: 2328.86 ================================================================================ project ├── columns: k:1!null i:2 f:3 s:4 j:5 @@ -958,7 +958,7 @@ EliminateSelect + └── y:8 = i:2 [outer=(2,8), constraints=(/2: (/NULL - ]; /8: (/NULL - ]), fd=(2)==(8), (8)==(2)] ================================================================================ PruneJoinLeftCols - Cost: 2297.36 + Cost: 2318.66 ================================================================================ project ├── columns: k:1!null i:2 f:3 s:4 j:5 @@ -982,7 +982,7 @@ PruneJoinLeftCols └── y:8 = i:2 [outer=(2,8), constraints=(/2: (/NULL - ]; /8: (/NULL - ]), fd=(2)==(8), (8)==(2)] ================================================================================ EliminateProject - Cost: 2287.35 + Cost: 2308.65 ================================================================================ -project +semi-join (hash) @@ -1020,7 +1020,7 @@ ReorderJoins (no changes) -------------------------------------------------------------------------------- ================================================================================ CommuteSemiJoin - Cost: 2214.42 + Cost: 2235.72 ================================================================================ -semi-join (hash) +project @@ -1087,7 +1087,7 @@ GenerateLookupJoins (no changes) -------------------------------------------------------------------------------- ================================================================================ Final best expression - Cost: 2214.42 + Cost: 2235.72 ================================================================================ project ├── columns: k:1!null i:2 f:3 s:4 j:5 @@ -1117,7 +1117,7 @@ SELECT 5=ANY(SELECT i FROM a WHERE k=x) AS r FROM xy ---- ================================================================================ Initial expression - Cost: 2219.67 + Cost: 2241.27 ================================================================================ project ├── columns: r:10 @@ -1148,7 +1148,7 @@ Initial expression └── 5 ================================================================================ PruneSelectCols - Cost: 2179.27 + Cost: 2200.47 ================================================================================ project ├── columns: r:10 @@ -1183,7 +1183,7 @@ PruneSelectCols └── 5 ================================================================================ PruneScanCols - Cost: 2159.07 + Cost: 2180.07 ================================================================================ project ├── columns: r:10 @@ -1216,7 +1216,7 @@ PruneScanCols └── 5 ================================================================================ HoistProjectSubquery - Cost: 2181.71 + Cost: 2202.71 ================================================================================ project ├── columns: r:10 @@ -1306,7 +1306,7 @@ HoistProjectSubquery + └── case:13 [as=r:10, outer=(13)] ================================================================================ CommuteVar - Cost: 2181.71 + Cost: 2202.71 ================================================================================ project ├── columns: r:10 @@ -1374,7 +1374,7 @@ CommuteVar └── case:13 [as=r:10, outer=(13)] ================================================================================ PushSelectIntoProject - Cost: 2181.71 + Cost: 2202.71 ================================================================================ project ├── columns: r:10 @@ -1454,7 +1454,7 @@ PushSelectIntoProject └── case:13 [as=r:10, outer=(13)] ================================================================================ MergeSelects - Cost: 2181.73 + Cost: 2202.73 ================================================================================ project ├── columns: r:10 @@ -1532,7 +1532,7 @@ MergeSelects └── case:13 [as=r:10, outer=(13)] ================================================================================ EliminateSelect - Cost: 2181.71 + Cost: 2202.71 ================================================================================ project ├── columns: r:10 @@ -1613,7 +1613,7 @@ EliminateSelect └── case:13 [as=r:10, outer=(13)] ================================================================================ MergeProjects - Cost: 2181.69 + Cost: 2202.69 ================================================================================ project ├── columns: r:10 @@ -1683,7 +1683,7 @@ MergeProjects └── case:13 [as=r:10, outer=(13)] ================================================================================ FoldNonNullIsNotNull - Cost: 2181.69 + Cost: 2202.69 ================================================================================ project ├── columns: r:10 @@ -1738,7 +1738,7 @@ FoldNonNullIsNotNull └── case:13 [as=r:10, outer=(13)] ================================================================================ SimplifyAndTrue - Cost: 2181.69 + Cost: 2202.69 ================================================================================ project ├── columns: r:10 @@ -1793,7 +1793,7 @@ SimplifyAndTrue └── case:13 [as=r:10, outer=(13)] ================================================================================ TryDecorrelateProject - Cost: 2211.68 + Cost: 2232.68 ================================================================================ project ├── columns: r:10 @@ -1883,7 +1883,7 @@ TryDecorrelateProject └── case:13 [as=r:10, outer=(13)] ================================================================================ TryDecorrelateScalarGroupBy - Cost: 2271.68 + Cost: 2292.68 ================================================================================ project ├── columns: r:10 @@ -1982,7 +1982,7 @@ TryDecorrelateScalarGroupBy └── case:13 [as=r:10, outer=(13)] ================================================================================ TryDecorrelateProjectSelect - Cost: 2309.14 + Cost: 2330.14 ================================================================================ project ├── columns: r:10 @@ -2068,7 +2068,7 @@ TryDecorrelateProjectSelect └── case:13 [as=r:10, outer=(13)] ================================================================================ DecorrelateJoin - Cost: 2309.14 + Cost: 2330.14 ================================================================================ project ├── columns: r:10 @@ -2131,7 +2131,7 @@ DecorrelateJoin └── case:13 [as=r:10, outer=(13)] ================================================================================ PushFilterIntoJoinRight - Cost: 2307.48 + Cost: 2328.48 ================================================================================ project ├── columns: r:10 @@ -2206,7 +2206,7 @@ PushFilterIntoJoinRight └── case:13 [as=r:10, outer=(13)] ================================================================================ PushSelectIntoProject - Cost: 2297.49 + Cost: 2318.49 ================================================================================ project ├── columns: r:10 @@ -2281,7 +2281,7 @@ PushSelectIntoProject └── case:13 [as=r:10, outer=(13)] ================================================================================ EliminateSelect - Cost: 2294.15 + Cost: 2315.15 ================================================================================ project ├── columns: r:10 @@ -2363,7 +2363,7 @@ EliminateSelect └── case:13 [as=r:10, outer=(13)] ================================================================================ PruneJoinRightCols - Cost: 2294.15 + Cost: 2315.15 ================================================================================ project ├── columns: r:10 @@ -2433,7 +2433,7 @@ PruneJoinRightCols └── case:13 [as=r:10, outer=(13)] ================================================================================ EliminateGroupByProject - Cost: 2284.14 + Cost: 2305.14 ================================================================================ project ├── columns: r:10 @@ -2524,7 +2524,7 @@ EliminateGroupByProject └── case:13 [as=r:10, outer=(13)] ================================================================================ EliminateProject - Cost: 2274.13 + Cost: 2295.13 ================================================================================ project ├── columns: r:10 @@ -2617,7 +2617,7 @@ EliminateProject └── case:13 [as=r:10, outer=(13)] ================================================================================ EliminateSelect - Cost: 2264.12 + Cost: 2285.12 ================================================================================ project ├── columns: r:10 @@ -2702,7 +2702,7 @@ EliminateSelect └── case:13 [as=r:10, outer=(13)] ================================================================================ EliminateSelect - Cost: 2254.11 + Cost: 2275.11 ================================================================================ project ├── columns: r:10 @@ -2788,7 +2788,7 @@ EliminateSelect └── case:13 [as=r:10, outer=(13)] ================================================================================ PruneProjectCols - Cost: 2254.11 + Cost: 2275.11 ================================================================================ project ├── columns: r:10 @@ -2837,7 +2837,7 @@ PruneProjectCols └── case:13 [as=r:10, outer=(13)] ================================================================================ InlineProjectInProject - Cost: 2234.10 + Cost: 2255.10 ================================================================================ project ├── columns: r:10 @@ -2977,7 +2977,7 @@ CommuteLeftJoin (higher cost) └── CASE WHEN bool_or:12 THEN true WHEN bool_or:12 IS NULL THEN false ELSE CAST(NULL AS BOOL) END [as=r:10, outer=(12)] ================================================================================ GenerateMergeJoins - Cost: 2229.09 + Cost: 2250.09 ================================================================================ project ├── columns: r:10 @@ -3554,7 +3554,7 @@ GenerateMergeJoins (no changes) -------------------------------------------------------------------------------- ================================================================================ GenerateStreamingGroupBy - Cost: 2219.09 + Cost: 2240.09 ================================================================================ project ├── columns: r:10 @@ -3602,7 +3602,7 @@ GenerateStreamingGroupBy └── CASE WHEN bool_or:12 THEN true WHEN bool_or:12 IS NULL THEN false ELSE CAST(NULL AS BOOL) END [as=r:10, outer=(12)] ================================================================================ Final best expression - Cost: 2219.09 + Cost: 2240.09 ================================================================================ project ├── columns: r:10 diff --git a/pkg/sql/opt/norm/testdata/rules/prune_cols b/pkg/sql/opt/norm/testdata/rules/prune_cols index 21da5674ef31..d1d00f185bd2 100644 --- a/pkg/sql/opt/norm/testdata/rules/prune_cols +++ b/pkg/sql/opt/norm/testdata/rules/prune_cols @@ -1837,17 +1837,17 @@ SELECT ntile(i) OVER () FROM a project ├── columns: ntile:6(int) ├── stats: [rows=1000] - ├── cost: 1074.53 + ├── cost: 1085.03 ├── prune: (6) └── window partition=() ├── columns: t.public.a.i:2(int) ntile:6(int) ├── stats: [rows=1000] - ├── cost: 1064.52 + ├── cost: 1075.02 ├── prune: (6) ├── scan t.public.a │ ├── columns: t.public.a.i:2(int) │ ├── stats: [rows=1000] - │ ├── cost: 1064.51 + │ ├── cost: 1075.01 │ └── prune: (2) └── windows └── ntile [as=ntile:6, type=int, outer=(2)] @@ -1955,17 +1955,17 @@ SELECT x FROM (SELECT ntile(i) OVER () x, ntile(f::int) OVER () y FROM a) project ├── columns: x:6(int) ├── stats: [rows=1000] - ├── cost: 1074.53 + ├── cost: 1085.03 ├── prune: (6) └── window partition=() ├── columns: t.public.a.i:2(int) ntile:6(int) ├── stats: [rows=1000] - ├── cost: 1064.52 + ├── cost: 1075.02 ├── prune: (6) ├── scan t.public.a │ ├── columns: t.public.a.i:2(int) │ ├── stats: [rows=1000] - │ ├── cost: 1064.51 + │ ├── cost: 1075.01 │ └── prune: (2) └── windows └── ntile [as=ntile:6, type=int, outer=(2)] @@ -4938,12 +4938,12 @@ WITH foo AS (SELECT * FROM a) with &1 (foo) ├── columns: i:7(int) ├── stats: [rows=1000] - ├── cost: 1094.83 + ├── cost: 1105.63 ├── prune: (7) ├── scan t.public.a │ ├── columns: t.public.a.k:1(int!null) t.public.a.i:2(int) t.public.a.f:3(float) t.public.a.s:4(string) │ ├── stats: [rows=1000] - │ ├── cost: 1094.81 + │ ├── cost: 1105.61 │ ├── key: (1) │ ├── fd: (1)-->(2-4) │ ├── prune: (1-4) diff --git a/pkg/sql/opt/norm/testdata/rules/scalar b/pkg/sql/opt/norm/testdata/rules/scalar index 297087215077..348d1059544b 100644 --- a/pkg/sql/opt/norm/testdata/rules/scalar +++ b/pkg/sql/opt/norm/testdata/rules/scalar @@ -1050,7 +1050,7 @@ SELECT k FROM e WHERE i IS NOT DISTINCT FROM NULL::FLOAT project ├── columns: k:1(int!null) ├── stats: [rows=10.0000001] - ├── cost: 14.5200001 + ├── cost: 24.9200001 ├── key: (1) ├── prune: (1) ├── interesting orderings: (+1) @@ -1058,7 +1058,7 @@ project ├── columns: t.public.e.k:1(int!null) t.public.e.i:2(int) ├── constraint: /2/1: [/NULL - /NULL] ├── stats: [rows=10.0000001, distinct(2)=1, null(2)=10] - ├── cost: 14.4100001 + ├── cost: 24.8100001 ├── key: (1) ├── fd: ()-->(2) ├── prune: (1) @@ -1070,7 +1070,7 @@ SELECT k FROM e WHERE i IS DISTINCT FROM NULL::FLOAT project ├── columns: k:1(int!null) ├── stats: [rows=990] - ├── cost: 1043.52 + ├── cost: 1053.92 ├── key: (1) ├── prune: (1) ├── interesting orderings: (+1) @@ -1078,7 +1078,7 @@ project ├── columns: t.public.e.k:1(int!null) t.public.e.i:2(int!null) ├── constraint: /2/1: (/NULL - ] ├── stats: [rows=990, distinct(2)=100, null(2)=0] - ├── cost: 1033.61 + ├── cost: 1044.01 ├── key: (1) ├── fd: (1)-->(2) ├── prune: (1) diff --git a/pkg/sql/opt/norm/testdata/rules/with b/pkg/sql/opt/norm/testdata/rules/with index 03d22e044560..8b29bba5e128 100644 --- a/pkg/sql/opt/norm/testdata/rules/with +++ b/pkg/sql/opt/norm/testdata/rules/with @@ -551,7 +551,7 @@ with &2 (cte) ├── cardinality: [1 - 2] ├── volatile, mutations ├── stats: [rows=2, distinct(12)=2, null(12)=0] - ├── cost: 1046.9075 + ├── cost: 1057.1075 ├── key: (12) ├── insert t.public.child │ ├── columns: t.public.child.c:1(int!null) @@ -562,7 +562,7 @@ with &2 (cte) │ ├── cardinality: [1 - 1] │ ├── volatile, mutations │ ├── stats: [rows=1, distinct(1)=1, null(1)=0] - │ ├── cost: 1046.7975 + │ ├── cost: 1056.9975 │ ├── key: () │ ├── fd: ()-->(1) │ ├── values @@ -582,7 +582,7 @@ with &2 (cte) │ ├── columns: p:6(int!null) │ ├── cardinality: [0 - 1] │ ├── stats: [rows=1e-10] - │ ├── cost: 1046.7675 + │ ├── cost: 1056.9675 │ ├── key: () │ ├── fd: ()-->(6) │ ├── cte-uses @@ -602,7 +602,7 @@ with &2 (cte) │ ├── scan t.public.parent │ │ ├── columns: t.public.parent.p:7(int!null) │ │ ├── stats: [rows=1000, distinct(7)=1000, null(7)=0] - │ │ ├── cost: 1034.21 + │ │ ├── cost: 1044.41 │ │ ├── key: (7) │ │ ├── prune: (7) │ │ ├── interesting orderings: (+7) diff --git a/pkg/sql/opt/optbuilder/testdata/aggregate b/pkg/sql/opt/optbuilder/testdata/aggregate index 40e520d932ab..d66bbf1746cb 100644 --- a/pkg/sql/opt/optbuilder/testdata/aggregate +++ b/pkg/sql/opt/optbuilder/testdata/aggregate @@ -3660,14 +3660,14 @@ group-by ├── columns: firstcol:1(int!null) secondcol:2(int) thirdcol:2(int) ├── grouping columns: t.public.xyz.x:1(int!null) t.public.xyz.y:2(int) ├── stats: [rows=1000, distinct(1,2)=1000, null(1,2)=0] - ├── cost: 1134.74 + ├── cost: 1145.44 ├── key: (1) ├── fd: (1)-->(2) ├── interesting orderings: (+1,+2) └── project ├── columns: t.public.xyz.x:1(int!null) t.public.xyz.y:2(int) ├── stats: [rows=1000, distinct(1,2)=1000, null(1,2)=0] - ├── cost: 1094.72 + ├── cost: 1105.42 ├── key: (1) ├── fd: (1)-->(2) ├── prune: (1,2) @@ -3675,7 +3675,7 @@ group-by └── scan t.public.xyz ├── columns: t.public.xyz.x:1(int!null) t.public.xyz.y:2(int) t.public.xyz.z:3(float) t.public.xyz.crdb_internal_mvcc_timestamp:4(decimal) ├── stats: [rows=1000, distinct(1,2)=1000, null(1,2)=0] - ├── cost: 1084.71 + ├── cost: 1095.41 ├── key: (1) ├── fd: (1)-->(2-4) ├── prune: (1-4) diff --git a/pkg/sql/opt/optgen/exprgen/testdata/explain b/pkg/sql/opt/optgen/exprgen/testdata/explain index a458022c24a3..c92f8bcc8c45 100644 --- a/pkg/sql/opt/optgen/exprgen/testdata/explain +++ b/pkg/sql/opt/optgen/exprgen/testdata/explain @@ -14,11 +14,11 @@ expr explain ├── mode: opt, verbose ├── stats: [rows=10] - ├── cost: 1064.52 + ├── cost: 1075.02 └── scan t.public.abc ├── columns: t.public.abc.a:1(int) ├── stats: [rows=1000] - ├── cost: 1064.51 + ├── cost: 1075.01 ├── prune: (1) └── interesting orderings: (+1) @@ -34,11 +34,11 @@ expr explain ├── mode: verbose ├── stats: [rows=10] - ├── cost: 1064.52 + ├── cost: 1075.02 └── scan t.public.abc ├── columns: t.public.abc.a:1(int) ├── stats: [rows=1000] - ├── cost: 1064.51 + ├── cost: 1075.01 ├── prune: (1) └── interesting orderings: (+1) @@ -54,11 +54,11 @@ expr explain ├── mode: opt ├── stats: [rows=10] - ├── cost: 1064.52 + ├── cost: 1075.02 └── scan t.public.abc ├── columns: t.public.abc.a:1(int) ├── stats: [rows=1000] - ├── cost: 1064.51 + ├── cost: 1075.01 ├── prune: (1) └── interesting orderings: (+1) @@ -81,17 +81,17 @@ expr explain ├── mode: opt ├── stats: [rows=10] - ├── cost: 1313.94569 + ├── cost: 1324.54569 └── sort ├── columns: a:1(int) [hidden: t.public.abc.b:2(int)] ├── stats: [rows=1000] - ├── cost: 1313.93569 + ├── cost: 1324.53569 ├── ordering: +2 ├── interesting orderings: (+1,+2) └── scan t.public.abc ├── columns: t.public.abc.a:1(int) t.public.abc.b:2(int) ├── stats: [rows=1000] - ├── cost: 1074.61 + ├── cost: 1085.21 └── interesting orderings: (+1,+2) expr @@ -106,10 +106,10 @@ expr explain ├── mode: distsql ├── stats: [rows=10] - ├── cost: 1064.52 + ├── cost: 1075.02 └── scan t.public.abc ├── columns: t.public.abc.a:1(int) ├── stats: [rows=1000] - ├── cost: 1064.51 + ├── cost: 1075.01 ├── prune: (1) └── interesting orderings: (+1) diff --git a/pkg/sql/opt/optgen/exprgen/testdata/join b/pkg/sql/opt/optgen/exprgen/testdata/join index cc6b4c2b7d3d..585f961e9cab 100644 --- a/pkg/sql/opt/optgen/exprgen/testdata/join +++ b/pkg/sql/opt/optgen/exprgen/testdata/join @@ -17,21 +17,21 @@ expr inner-join (hash) ├── columns: t.public.abc.a:1(int!null) t.public.abc.b:2(int) t.public.abc.c:3(int) t.public.def.d:6(int!null) t.public.def.e:7(int) t.public.def.f:8(int) ├── stats: [rows=9801, distinct(1)=99, null(1)=0, distinct(6)=99, null(6)=0] - ├── cost: 2297.45 + ├── cost: 2318.85 ├── fd: (1)==(6), (6)==(1) ├── prune: (2,3,7,8) ├── interesting orderings: (+1,+2) ├── scan t.public.abc │ ├── columns: t.public.abc.a:1(int) t.public.abc.b:2(int) t.public.abc.c:3(int) │ ├── stats: [rows=1000, distinct(1)=100, null(1)=10] - │ ├── cost: 1084.71 + │ ├── cost: 1095.41 │ ├── prune: (1-3) │ ├── interesting orderings: (+1,+2) │ └── unfiltered-cols: (1-5) ├── scan t.public.def │ ├── columns: t.public.def.d:6(int) t.public.def.e:7(int) t.public.def.f:8(int) │ ├── stats: [rows=1000, distinct(6)=100, null(6)=10] - │ ├── cost: 1084.71 + │ ├── cost: 1095.41 │ ├── prune: (6-8) │ └── unfiltered-cols: (6-10) └── filters @@ -50,11 +50,11 @@ left-join (lookup t.public.abc@ab) ├── columns: t.public.abc.a:6(int) t.public.abc.b:7(int) ├── key columns: [6] = [6] ├── stats: [rows=3333.33333, distinct(6)=100, null(6)=33.3333333] - ├── cost: 41674.63 + ├── cost: 41685.23 ├── scan t.public.def │ ├── columns: t.public.def.d:1(int) t.public.def.e:2(int) │ ├── stats: [rows=1000, distinct(2)=100, null(2)=10] - │ ├── cost: 1074.61 + │ ├── cost: 1085.21 │ └── prune: (1,2) └── filters └── gt [type=bool, outer=(2,6), constraints=(/2: (/NULL - ]; /6: (/NULL - ])] @@ -80,31 +80,31 @@ inner-join (merge) ├── left ordering: +1 ├── right ordering: +6 ├── stats: [rows=9801, distinct(1)=99, null(1)=0, distinct(6)=99, null(6)=0] - ├── cost: 2786.09137 + ├── cost: 2807.49137 ├── fd: (1)==(6), (6)==(1) ├── sort │ ├── columns: t.public.abc.a:1(int) t.public.abc.b:2(int) t.public.abc.c:3(int) │ ├── stats: [rows=1000, distinct(1)=100, null(1)=10] - │ ├── cost: 1334.03569 + │ ├── cost: 1344.73569 │ ├── ordering: +1 │ ├── prune: (1-3) │ ├── interesting orderings: (+1,+2) │ └── scan t.public.abc │ ├── columns: t.public.abc.a:1(int) t.public.abc.b:2(int) t.public.abc.c:3(int) │ ├── stats: [rows=1000, distinct(1)=100, null(1)=10] - │ ├── cost: 1084.71 + │ ├── cost: 1095.41 │ ├── prune: (1-3) │ └── interesting orderings: (+1,+2) ├── sort │ ├── columns: t.public.def.d:6(int) t.public.def.e:7(int) t.public.def.f:8(int) │ ├── stats: [rows=1000, distinct(6)=100, null(6)=10] - │ ├── cost: 1334.03569 + │ ├── cost: 1344.73569 │ ├── ordering: +6 │ ├── prune: (6-8) │ └── scan t.public.def │ ├── columns: t.public.def.d:6(int) t.public.def.e:7(int) t.public.def.f:8(int) │ ├── stats: [rows=1000, distinct(6)=100, null(6)=10] - │ ├── cost: 1084.71 + │ ├── cost: 1095.41 │ └── prune: (6-8) └── filters (true) @@ -123,30 +123,30 @@ inner-join-apply ├── columns: t.public.abc.a:1(int) t.public.abc.b:2(int) t.public.abc.c:3(int) t.public.def.d:6(int) t.public.def.e:7(int) t.public.def.f:8(int) ├── immutable ├── stats: [rows=333333.333] - ├── cost: 5670.78451 + ├── cost: 5692.18451 ├── prune: (8) ├── interesting orderings: (+1,+2) ├── sort │ ├── columns: t.public.abc.a:1(int) t.public.abc.b:2(int) t.public.abc.c:3(int) │ ├── stats: [rows=1000] - │ ├── cost: 1224.37784 + │ ├── cost: 1235.07784 │ ├── interesting orderings: (+1,+2) │ └── scan t.public.abc │ ├── columns: t.public.abc.a:1(int) t.public.abc.b:2(int) t.public.abc.c:3(int) │ ├── stats: [rows=1000] - │ ├── cost: 1084.71 + │ ├── cost: 1095.41 │ └── interesting orderings: (+1,+2) ├── select │ ├── columns: t.public.def.d:6(int) t.public.def.e:7(int) t.public.def.f:8(int) │ ├── outer: (1) │ ├── immutable │ ├── stats: [rows=333.333333, distinct(1)=1, null(1)=0] - │ ├── cost: 1094.73 + │ ├── cost: 1105.43 │ ├── prune: (8) │ ├── scan t.public.def │ │ ├── columns: t.public.def.d:6(int) t.public.def.e:7(int) t.public.def.f:8(int) │ │ ├── stats: [rows=1000] - │ │ ├── cost: 1084.71 + │ │ ├── cost: 1095.41 │ │ └── prune: (6-8) │ └── filters │ └── eq [type=bool, outer=(1,6,7), immutable, constraints=(/1: (/NULL - ])] diff --git a/pkg/sql/opt/optgen/exprgen/testdata/limit b/pkg/sql/opt/optgen/exprgen/testdata/limit index fbccdbb6541a..2331679e3f5c 100644 --- a/pkg/sql/opt/optgen/exprgen/testdata/limit +++ b/pkg/sql/opt/optgen/exprgen/testdata/limit @@ -39,18 +39,18 @@ limit ├── internal-ordering: +1 ├── cardinality: [0 - 10] ├── stats: [rows=10] - ├── cost: 1314.04569 + ├── cost: 1324.64569 ├── interesting orderings: (+1,+2) ├── sort │ ├── columns: t.public.abc.a:1(int) t.public.abc.b:2(int) │ ├── stats: [rows=1000] - │ ├── cost: 1313.93569 + │ ├── cost: 1324.53569 │ ├── ordering: +1 │ ├── limit hint: 10.00 │ ├── interesting orderings: (+1,+2) │ └── scan t.public.abc │ ├── columns: t.public.abc.a:1(int) t.public.abc.b:2(int) │ ├── stats: [rows=1000] - │ ├── cost: 1074.61 + │ ├── cost: 1085.21 │ └── interesting orderings: (+1,+2) └── const: 10 [type=int] diff --git a/pkg/sql/opt/optgen/exprgen/testdata/scan b/pkg/sql/opt/optgen/exprgen/testdata/scan index 505423dd40c0..894d3fbc2ee7 100644 --- a/pkg/sql/opt/optgen/exprgen/testdata/scan +++ b/pkg/sql/opt/optgen/exprgen/testdata/scan @@ -8,7 +8,7 @@ expr scan t.public.abc ├── columns: t.public.abc.a:1(int) ├── stats: [rows=1000] - ├── cost: 1064.51 + ├── cost: 1075.01 ├── prune: (1) └── interesting orderings: (+1) @@ -18,7 +18,7 @@ expr scan t.public.abc@ab ├── columns: t.public.abc.a:1(int) t.public.abc.b:2(int) ├── stats: [rows=1000] - ├── cost: 1064.51 + ├── cost: 1075.01 ├── prune: (1,2) └── interesting orderings: (+1,+2) @@ -32,7 +32,7 @@ expr scan t.public.abc@ab ├── columns: a:1(int) b:2(int) ├── stats: [rows=1000] - ├── cost: 1064.51 + ├── cost: 1075.01 ├── ordering: +1,+2 ├── prune: (1,2) └── interesting orderings: (+1,+2) @@ -46,14 +46,14 @@ expr select ├── columns: t.public.abc.a:1(int!null) t.public.abc.b:2(int) t.public.abc.c:3(int) ├── stats: [rows=10, distinct(1)=1, null(1)=0] - ├── cost: 1094.73 + ├── cost: 1105.43 ├── fd: ()-->(1) ├── prune: (2,3) ├── interesting orderings: (+1,+2) ├── scan t.public.abc │ ├── columns: t.public.abc.a:1(int) t.public.abc.b:2(int) t.public.abc.c:3(int) │ ├── stats: [rows=1000, distinct(1)=100, null(1)=10] - │ ├── cost: 1084.71 + │ ├── cost: 1095.41 │ ├── prune: (1-3) │ └── interesting orderings: (+1,+2) └── filters diff --git a/pkg/sql/opt/props/cardinality.go b/pkg/sql/opt/props/cardinality.go index 8e09022beba9..e50e7ed9c431 100644 --- a/pkg/sql/opt/props/cardinality.go +++ b/pkg/sql/opt/props/cardinality.go @@ -57,6 +57,11 @@ func (c Cardinality) CanBeZero() bool { return c.Min == 0 } +// IsUnbounded returns true if the expression has unbounded maximum cardinality. +func (c Cardinality) IsUnbounded() bool { + return c.Max == AnyCardinality.Max +} + // AsLowAs ratchets the min bound downwards in order to ensure that it allows // values that are >= the min value. func (c Cardinality) AsLowAs(min uint32) Cardinality { diff --git a/pkg/sql/opt/testutils/opttester/testdata/opt-steps b/pkg/sql/opt/testutils/opttester/testdata/opt-steps index 18d9e9f50aa3..aca9fb3e3383 100644 --- a/pkg/sql/opt/testutils/opttester/testdata/opt-steps +++ b/pkg/sql/opt/testutils/opttester/testdata/opt-steps @@ -55,7 +55,7 @@ SELECT * FROM ab WHERE b=1 ---- ================================================================================ Initial expression - Cost: 1074.64 + Cost: 1085.14 ================================================================================ project ├── columns: a:1(int!null) b:2(int!null) @@ -75,7 +75,7 @@ Initial expression └── const: 1 [type=int] ================================================================================ PruneSelectCols - Cost: 1064.54 + Cost: 1074.94 ================================================================================ project ├── columns: a:1(int!null) b:2(int!null) @@ -99,7 +99,7 @@ PruneSelectCols └── const: 1 [type=int] ================================================================================ EliminateProject - Cost: 1064.43 + Cost: 1074.83 ================================================================================ -project +select @@ -147,7 +147,7 @@ GeneratePartialIndexScans (no changes) -------------------------------------------------------------------------------- ================================================================================ GenerateConstrainedScans - Cost: 14.41 + Cost: 24.81 ================================================================================ -select +scan ab@secondary @@ -169,7 +169,7 @@ GenerateZigzagJoins (no changes) -------------------------------------------------------------------------------- ================================================================================ Final best expression - Cost: 14.41 + Cost: 24.81 ================================================================================ scan ab@secondary ├── columns: a:1(int!null) b:2(int!null) @@ -208,7 +208,7 @@ SELECT * FROM orders LEFT JOIN customers ON customer_id = customers.id ---- ================================================================================ Initial expression - Cost: 2219.45 + Cost: 2240.85 ================================================================================ project ├── columns: id:1(int!null) customer_id:2(int) status:3(string!null) id:5(int) name:6(string) address:7(string) @@ -240,7 +240,7 @@ Initial expression └── variable: customers.id:5 [type=int] ================================================================================ NormalizeInConst - Cost: 2219.45 + Cost: 2240.85 ================================================================================ project ├── columns: id:1(int!null) customer_id:2(int) status:3(string!null) id:5(int) name:6(string) address:7(string) @@ -274,7 +274,7 @@ NormalizeInConst └── variable: customers.id:5 [type=int] ================================================================================ PruneJoinLeftCols - Cost: 2209.35 + Cost: 2230.65 ================================================================================ project ├── columns: id:1(int!null) customer_id:2(int) status:3(string!null) id:5(int) name:6(string) address:7(string) @@ -310,7 +310,7 @@ PruneJoinLeftCols └── variable: customers.id:5 [type=int] ================================================================================ PruneJoinRightCols - Cost: 2199.25 + Cost: 2220.45 ================================================================================ project ├── columns: id:1(int!null) customer_id:2(int) status:3(string!null) id:5(int) name:6(string) address:7(string) @@ -346,7 +346,7 @@ PruneJoinRightCols └── variable: customers.id:5 [type=int] ================================================================================ EliminateProject - Cost: 2189.24 + Cost: 2210.44 ================================================================================ -project +left-join (hash) @@ -641,7 +641,7 @@ GenerateMergeJoins (no changes) -------------------------------------------------------------------------------- ================================================================================ Final best expression - Cost: 2189.24 + Cost: 2210.44 ================================================================================ left-join (hash) ├── columns: id:1(int!null) customer_id:2(int) status:3(string!null) id:5(int) name:6(string) address:7(string) @@ -684,7 +684,7 @@ SELECT * FROM comp WHERE k=1 ---- ================================================================================ Initial expression - Cost: 1094.84 + Cost: 1105.54 ================================================================================ project ├── columns: k:1(int!null) c:2(bool) @@ -711,7 +711,7 @@ Initial expression └── const: 1 [type=int] ================================================================================ NormalizeInConst - Cost: 1094.84 + Cost: 1105.54 ================================================================================ project ├── columns: k:1(int!null) c:2(bool) @@ -740,7 +740,7 @@ NormalizeInConst └── const: 1 [type=int] ================================================================================ PruneSelectCols - Cost: 1074.64 + Cost: 1085.14 ================================================================================ project ├── columns: k:1(int!null) c:2(bool) @@ -771,7 +771,7 @@ PruneSelectCols └── const: 1 [type=int] ================================================================================ EliminateProject - Cost: 1074.53 + Cost: 1085.03 ================================================================================ -project +select @@ -840,7 +840,7 @@ GenerateConstrainedScans (no changes) -------------------------------------------------------------------------------- ================================================================================ FoldComparison - Cost: 14.51 + Cost: 25.01 ================================================================================ -select +scan comp@secondary @@ -868,7 +868,7 @@ GenerateZigzagJoins (no changes) -------------------------------------------------------------------------------- ================================================================================ Final best expression - Cost: 14.51 + Cost: 25.01 ================================================================================ scan comp@secondary ├── columns: k:1(int!null) c:2(bool) @@ -888,7 +888,7 @@ SELECT i FROM (SELECT i FROM t WHERE i > 10 AND i < 20) AS t2 WHERE i = 5 ---- ================================================================================ Initial expression - Cost: 1076.36 + Cost: 1086.86 ================================================================================ select ├── columns: i:1(int!null) @@ -917,7 +917,7 @@ Initial expression └── const: 5 [type=int] ================================================================================ SimplifySelectFilters - Cost: 1081.24 + Cost: 1091.74 ================================================================================ select ├── columns: i:1(int!null) @@ -952,7 +952,7 @@ SimplifySelectFilters └── const: 5 [type=int] ================================================================================ ConsolidateSelectFilters - Cost: 1076.36 + Cost: 1086.86 ================================================================================ select ├── columns: i:1(int!null) @@ -988,7 +988,7 @@ ConsolidateSelectFilters └── const: 5 [type=int] ================================================================================ PruneSelectCols - Cost: 1056.16 + Cost: 1066.46 ================================================================================ select ├── columns: i:1(int!null) @@ -1020,7 +1020,7 @@ PruneSelectCols └── const: 5 [type=int] ================================================================================ EliminateProject - Cost: 1055.25 + Cost: 1065.55 ================================================================================ select ├── columns: i:1(int!null) @@ -1058,7 +1058,7 @@ EliminateProject └── const: 5 [type=int] ================================================================================ MergeSelects - Cost: 1054.34 + Cost: 1064.64 ================================================================================ select ├── columns: i:1(int!null) @@ -1092,7 +1092,7 @@ MergeSelects └── const: 5 [type=int] ================================================================================ InlineConstVar - Cost: 1054.34 + Cost: 1064.64 ================================================================================ select ├── columns: i:1(int!null) @@ -1116,7 +1116,7 @@ InlineConstVar └── const: 5 [type=int] ================================================================================ FoldComparison - Cost: 1054.34 + Cost: 1064.64 ================================================================================ select ├── columns: i:1(int!null) @@ -1140,7 +1140,7 @@ FoldComparison └── const: 5 [type=int] ================================================================================ FoldComparison - Cost: 1054.34 + Cost: 1064.64 ================================================================================ select ├── columns: i:1(int!null) @@ -1161,7 +1161,7 @@ FoldComparison └── const: 5 [type=int] ================================================================================ SimplifyAndTrue - Cost: 1054.34 + Cost: 1064.64 ================================================================================ select ├── columns: i:1(int!null) @@ -1180,7 +1180,7 @@ SimplifyAndTrue └── const: 5 [type=int] ================================================================================ SimplifyRange - Cost: 1054.34 + Cost: 1064.64 ================================================================================ select ├── columns: i:1(int!null) @@ -1197,7 +1197,7 @@ SimplifyRange └── const: 5 [type=int] ================================================================================ SimplifySelectFilters - Cost: 1054.33 + Cost: 1064.63 ================================================================================ select - ├── columns: i:1(int!null) diff --git a/pkg/sql/opt/xform/coster.go b/pkg/sql/opt/xform/coster.go index 73883e35f549..5ce58fd48802 100644 --- a/pkg/sql/opt/xform/coster.go +++ b/pkg/sql/opt/xform/coster.go @@ -19,6 +19,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/opt/cat" "github.com/cockroachdb/cockroach/pkg/sql/opt/memo" "github.com/cockroachdb/cockroach/pkg/sql/opt/ordering" + "github.com/cockroachdb/cockroach/pkg/sql/opt/props" "github.com/cockroachdb/cockroach/pkg/sql/opt/props/physical" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" "github.com/cockroachdb/cockroach/pkg/util" @@ -139,6 +140,18 @@ const ( // surprising to users (like full scans instead of point lookups). fullScanRowCountPenalty = 10 + // unboundedMaxCardinalityScanRowCountPenalty adds a penalty to scans with + // unbounded maximum cardinality. This helps prevent surprising plans for very + // small tables or for when stats are stale. For full table scans, this + // penalty is added on top of the fullScanRowCountPenalty. + unboundedMaxCardinalityScanRowCountPenalty = fullScanRowCountPenalty + + // largeMaxCardinalityScanRowCountPenalty is the maximum penalty to add to + // scans with a bounded maximum cardinality exceeding the row count estimate. + // This helps prevent surprising plans for very small tables or for when stats + // are stale. + largeMaxCardinalityScanRowCountPenalty = unboundedMaxCardinalityScanRowCountPenalty / 2 + // preferLookupJoinFactor is a scale factor for the cost of a lookup join when // we have a hint for preferring a lookup join. preferLookupJoinFactor = 1e-6 @@ -622,6 +635,11 @@ func (c *coster) computeScanCost(scan *memo.ScanExpr, required *physical.Require } } + // Add a penalty if the cardinality exceeds the row count estimate. Adding a + // few rows worth of cost helps prevent surprising plans for very small tables + // or for when stats are stale. + rowCount += c.largeCardinalityRowCountPenalty(scan.Relational().Cardinality, rowCount) + if required.LimitHint != 0 { rowCount = math.Min(rowCount, required.LimitHint) } @@ -1012,6 +1030,12 @@ func (c *coster) computeZigzagJoinCost(join *memo.ZigzagJoinExpr) memo.Cost { filterSetup, filterPerRow := c.computeFiltersCost(join.On, util.FastIntMap{}) + // Add a penalty if the cardinality exceeds the row count estimate. Adding a + // few rows worth of cost helps prevent surprising plans for very small tables + // or for when stats are stale. This is also needed to ensure parity with the + // cost of scans. + rowCount += c.largeCardinalityRowCountPenalty(join.Relational().Cardinality, rowCount) + // Double the cost of emitting rows as well as the cost of seeking rows, // given two indexes will be accessed. cost := memo.Cost(rowCount) * (2*(cpuCostFactor+seqIOCostFactor) + scanCost + filterPerRow) @@ -1174,6 +1198,27 @@ func (c *coster) rowScanCost(tabID opt.TableID, idxOrd int, numScannedCols int) return memo.Cost(numCols+numScannedCols) * costFactor } +// largeCardinalityRowCountPenalty returns a penalty that should be added to the +// row count of scans. It is non-zero for expressions with unbounded maximum +// cardinality or with maximum cardinality exceeding the row count estimate. +// Adding a few rows worth of cost helps prevent surprising plans for very small +// tables or for when stats are stale. +func (c *coster) largeCardinalityRowCountPenalty( + cardinality props.Cardinality, rowCount float64, +) float64 { + if cardinality.IsUnbounded() { + return unboundedMaxCardinalityScanRowCountPenalty + } + if maxCard := float64(cardinality.Max); maxCard > rowCount { + penalty := maxCard - rowCount + if penalty > largeMaxCardinalityScanRowCountPenalty { + penalty = largeMaxCardinalityScanRowCountPenalty + } + return penalty + } + return 0 +} + // localityMatchScore returns a number from 0.0 to 1.0 that describes how well // the current node's locality matches the given zone constraints and // leaseholder preferences, with 0.0 indicating 0% and 1.0 indicating 100%. This diff --git a/pkg/sql/opt/xform/testdata/coster/groupby b/pkg/sql/opt/xform/testdata/coster/groupby index 7a0ff1ad6e89..fdb822e006ab 100644 --- a/pkg/sql/opt/xform/testdata/coster/groupby +++ b/pkg/sql/opt/xform/testdata/coster/groupby @@ -9,13 +9,13 @@ group-by ├── columns: max:6!null min:7!null i:2 s:3 ├── grouping columns: i:2 s:3 ├── stats: [rows=1000, distinct(2,3)=1000, null(2,3)=0.1] - ├── cost: 1144.73 + ├── cost: 1155.43 ├── key: (2,3) ├── fd: (2,3)-->(6,7) ├── scan a │ ├── columns: k:1!null i:2 s:3 │ ├── stats: [rows=1000, distinct(2,3)=1000, null(2,3)=0.1] - │ ├── cost: 1084.71 + │ ├── cost: 1095.41 │ ├── key: (1) │ └── fd: (1)-->(2,3) └── aggregations diff --git a/pkg/sql/opt/xform/testdata/coster/join b/pkg/sql/opt/xform/testdata/coster/join index 17639c4f977b..ee20a581c4a2 100644 --- a/pkg/sql/opt/xform/testdata/coster/join +++ b/pkg/sql/opt/xform/testdata/coster/join @@ -17,30 +17,30 @@ project ├── columns: k:1!null x:6!null ├── immutable ├── stats: [rows=99] - ├── cost: 2153.725 + ├── cost: 2174.725 ├── fd: (1)==(6), (6)==(1) └── inner-join (hash) ├── columns: k:1!null d:4!null x:6!null ├── multiplicity: left-rows(zero-or-one), right-rows(zero-or-more) ├── immutable ├── stats: [rows=99, distinct(1)=10, null(1)=0, distinct(6)=10, null(6)=0] - ├── cost: 2152.725 + ├── cost: 2173.725 ├── fd: ()-->(4), (1)==(6), (6)==(1) ├── scan b │ ├── columns: x:6 │ ├── stats: [rows=1000, distinct(6)=100, null(6)=10] - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── select │ ├── columns: k:1!null d:4!null │ ├── immutable │ ├── stats: [rows=10, distinct(1)=10, null(1)=0, distinct(4)=1, null(4)=0] - │ ├── cost: 1084.63 + │ ├── cost: 1095.23 │ ├── key: (1) │ ├── fd: ()-->(4) │ ├── scan a │ │ ├── columns: k:1!null d:4!null │ │ ├── stats: [rows=1000, distinct(1)=1000, null(1)=0, distinct(4)=100, null(4)=0] - │ │ ├── cost: 1074.61 + │ │ ├── cost: 1085.21 │ │ ├── key: (1) │ │ └── fd: (1)-->(4) │ └── filters @@ -58,23 +58,23 @@ inner-join (merge) ├── left ordering: +1 ├── right ordering: +6 ├── stats: [rows=990, distinct(1)=99, null(1)=0, distinct(6)=99, null(6)=0] - ├── cost: 2378.15569 + ├── cost: 2399.05569 ├── fd: (1)==(6), (6)==(1) ├── scan a │ ├── columns: k:1!null │ ├── stats: [rows=1000, distinct(1)=1000, null(1)=0] - │ ├── cost: 1064.51 + │ ├── cost: 1075.01 │ ├── key: (1) │ └── ordering: +1 ├── sort │ ├── columns: x:6 │ ├── stats: [rows=1000, distinct(6)=100, null(6)=10] - │ ├── cost: 1283.73569 + │ ├── cost: 1294.13569 │ ├── ordering: +6 │ └── scan b │ ├── columns: x:6 │ ├── stats: [rows=1000, distinct(6)=100, null(6)=10] - │ └── cost: 1054.41 + │ └── cost: 1064.81 └── filters (true) # Verify that we pick lookup join if we force it. Note that lookup join is only @@ -88,12 +88,12 @@ inner-join (lookup a) ├── key columns: [1] = [5] ├── lookup columns are key ├── stats: [rows=990, distinct(1)=99, null(1)=0, distinct(5)=99, null(5)=0] - ├── cost: 7093.82 + ├── cost: 7104.22 ├── fd: (1)==(5), (5)==(1) ├── scan b │ ├── columns: x:1 │ ├── stats: [rows=1000, distinct(1)=100, null(1)=10] - │ └── cost: 1054.41 + │ └── cost: 1064.81 └── filters (true) @@ -112,12 +112,12 @@ inner-join (hash) ├── scan a │ ├── columns: k:1!null │ ├── stats: [rows=1000, distinct(1)=1000, null(1)=0] - │ ├── cost: 1064.51 + │ ├── cost: 1075.01 │ └── key: (1) ├── scan b │ ├── columns: x:6 │ ├── stats: [rows=1000, distinct(6)=100, null(6)=10] - │ └── cost: 1054.41 + │ └── cost: 1064.81 └── filters └── k:1 = x:6 [outer=(1,6), constraints=(/1: (/NULL - ]; /6: (/NULL - ]), fd=(1)==(6), (6)==(1)] @@ -131,7 +131,7 @@ inner-join (lookup g [as=g2]) ├── lookup columns are key ├── immutable ├── stats: [rows=9801] - ├── cost: 1101954.44 + ├── cost: 1101964.84 ├── key: (1,5) ├── fd: (1)-->(2), (5)-->(6) ├── inner-join (inverted g@secondary [as=g2]) @@ -140,13 +140,13 @@ inner-join (lookup g [as=g2]) │ ├── inverted-expr │ │ └── st_contains(g1.geom:2, g2.geom:10) │ ├── stats: [rows=10000, distinct(1)=999.956829, null(1)=0, distinct(9)=999.956829, null(9)=0] - │ ├── cost: 41454.42 + │ ├── cost: 41464.82 │ ├── key: (1,9) │ ├── fd: (1)-->(2) │ ├── scan g [as=g1] │ │ ├── columns: g1.k:1!null g1.geom:2 │ │ ├── stats: [rows=1000, distinct(1)=1000, null(1)=0, distinct(2)=100, null(2)=10] - │ │ ├── cost: 1054.41 + │ │ ├── cost: 1064.81 │ │ ├── key: (1) │ │ └── fd: (1)-->(2) │ └── filters (true) @@ -169,13 +169,13 @@ inner-join (cross) ├── scan g [as=g1] │ ├── columns: g1.k:1!null g1.geom:2 │ ├── stats: [rows=1000] - │ ├── cost: 1054.41 + │ ├── cost: 1064.81 │ ├── key: (1) │ └── fd: (1)-->(2) ├── scan g [as=g2] │ ├── columns: g2.k:5!null g2.geom:6 │ ├── stats: [rows=1000, distinct(5)=1000, null(5)=0] - │ ├── cost: 1054.41 + │ ├── cost: 1064.81 │ ├── key: (5) │ └── fd: (5)-->(6) └── filters @@ -213,16 +213,16 @@ inner-join (lookup a) ├── key columns: [7] = [1] ├── lookup columns are key ├── stats: [rows=10000, distinct(1)=1000, null(1)=0, distinct(7)=1000, null(7)=0] - ├── cost: 71514.54 + ├── cost: 71525.04 ├── fd: (1)-->(2-4), (1)==(7), (7)==(1) ├── select │ ├── columns: x:6!null z:7!null │ ├── stats: [rows=10000, distinct(6)=1000, null(6)=0, distinct(7)=1000, null(7)=0] - │ ├── cost: 10614.53 + │ ├── cost: 10625.03 │ ├── scan b │ │ ├── columns: x:6 z:7!null │ │ ├── stats: [rows=10000, distinct(6)=1000, null(6)=0, distinct(7)=1000, null(7)=0] - │ │ └── cost: 10514.51 + │ │ └── cost: 10525.01 │ └── filters │ └── (x:6 > 0) AND (x:6 <= 5000) [outer=(6), constraints=(/6: [/1 - /5000]; tight)] └── filters (true) @@ -401,14 +401,14 @@ SELECT * FROM abc WHERE c = 1 index-join abc ├── columns: a:1!null b:2 c:3!null ├── stats: [rows=9.9005002, distinct(3)=1, null(3)=0] - ├── cost: 74.2145464 + ├── cost: 84.6145464 ├── key: (1) ├── fd: ()-->(3), (1)-->(2) └── scan abc@c_idx ├── columns: a:1!null c:3!null ├── constraint: /3/1: [/1 - /1] ├── stats: [rows=9.9005002, distinct(3)=1, null(3)=0] - ├── cost: 14.3065202 + ├── cost: 24.7065202 ├── key: (1) └── fd: ()-->(3) @@ -492,23 +492,23 @@ WHERE w = 'foo' AND x = '2AB23800-06B1-4E19-A3BB-DF3768B808D2' project ├── columns: w:1!null x:2!null y:3!null z:4!null ├── stats: [rows=500.488759] - ├── cost: 3174.98489 + ├── cost: 3185.88489 ├── fd: ()-->(1,2) └── inner-join (lookup abcde@idx_abcd) ├── columns: w:1!null x:2!null y:3!null z:4!null a:7!null b:8!null c:9!null ├── key columns: [1 2 3] = [7 8 9] ├── stats: [rows=500.488759, distinct(1)=1, null(1)=0, distinct(2)=1, null(2)=0, distinct(3)=25, null(3)=0, distinct(7)=1, null(7)=0, distinct(8)=1, null(8)=0, distinct(9)=25, null(9)=0] - ├── cost: 3169.97 + ├── cost: 3180.87 ├── fd: ()-->(1,2,7,8), (1)==(7), (7)==(1), (2)==(8), (8)==(2), (3)==(9), (9)==(3) ├── select │ ├── columns: w:1!null x:2!null y:3!null z:4!null │ ├── stats: [rows=100, distinct(1)=1, null(1)=0, distinct(2)=1, null(2)=0, distinct(3)=25, null(3)=0, distinct(4)=10, null(4)=0] - │ ├── cost: 124.94 + │ ├── cost: 135.84 │ ├── fd: ()-->(1,2) │ ├── scan wxyz │ │ ├── columns: w:1!null x:2!null y:3!null z:4!null │ │ ├── stats: [rows=100, distinct(1)=1, null(1)=0, distinct(2)=1, null(2)=0, distinct(3)=25, null(3)=0, distinct(4)=10, null(4)=0] - │ │ └── cost: 123.91 + │ │ └── cost: 134.81 │ └── filters │ ├── w:1 = 'foo' [outer=(1), constraints=(/1: [/'foo' - /'foo']; tight), fd=()-->(1)] │ └── x:2 = '2ab23800-06b1-4e19-a3bb-df3768b808d2' [outer=(2), constraints=(/2: [/'2ab23800-06b1-4e19-a3bb-df3768b808d2' - /'2ab23800-06b1-4e19-a3bb-df3768b808d2']; tight), fd=()-->(2)] @@ -602,23 +602,23 @@ WHERE w = 'foo' AND x = '2AB23800-06B1-4E19-A3BB-DF3768B808D2' AND (i,j,k,l,m,n) project ├── columns: w:1!null x:2!null y:3!null z:4!null ├── stats: [rows=4.50439933] - ├── cost: 12243.69 + ├── cost: 12255.79 ├── fd: ()-->(1,2) └── inner-join (lookup abcde@idx_abcd) ├── columns: w:1!null x:2!null y:3!null z:4!null i:5!null j:6!null k:7!null l:8!null m:9!null n:10!null a:13!null b:14!null c:15!null ├── key columns: [1 2 3] = [13 14 15] ├── stats: [rows=4.50439933, distinct(1)=0.9000001, null(1)=0, distinct(2)=0.9000001, null(2)=0, distinct(3)=0.88403183, null(3)=0, distinct(13)=0.9000001, null(13)=0, distinct(14)=0.9000001, null(14)=0, distinct(15)=0.88403183, null(15)=0] - ├── cost: 12243.635 + ├── cost: 12255.735 ├── fd: ()-->(1,2,5-10,13,14), (1)==(13), (13)==(1), (2)==(14), (14)==(2), (3)==(15), (15)==(3) ├── select │ ├── columns: w:1!null x:2!null y:3!null z:4!null i:5!null j:6!null k:7!null l:8!null m:9!null n:10!null │ ├── stats: [rows=0.9000001, distinct(1)=0.9000001, null(1)=0, distinct(2)=0.9000001, null(2)=0, distinct(3)=0.88403183, null(3)=0, distinct(4)=0.899635687, null(4)=0, distinct(5)=0.9000001, null(5)=0, distinct(6)=0.9000001, null(6)=0, distinct(7)=0.9000001, null(7)=0, distinct(8)=0.9000001, null(8)=0, distinct(9)=0.9000001, null(9)=0, distinct(10)=0.9000001, null(10)=0, distinct(5-10)=0.9000001, null(5-10)=0] - │ ├── cost: 12216.2 + │ ├── cost: 12228.3 │ ├── fd: ()-->(1,2,5-10) │ ├── scan wxyzijklmn │ │ ├── columns: w:1!null x:2!null y:3!null z:4!null i:5 j:6 k:7 l:8 m:9 n:10 │ │ ├── stats: [rows=10000, distinct(1)=1, null(1)=0, distinct(2)=1, null(2)=0, distinct(3)=25, null(3)=0, distinct(4)=1000, null(4)=0, distinct(5)=10000, null(5)=0, distinct(6)=10000, null(6)=0, distinct(7)=10000, null(7)=0, distinct(8)=10000, null(8)=0, distinct(9)=10000, null(9)=0, distinct(10)=10000, null(10)=0, distinct(5-10)=10000, null(5-10)=0] - │ │ └── cost: 12116.11 + │ │ └── cost: 12128.21 │ └── filters │ ├── w:1 = 'foo' [outer=(1), constraints=(/1: [/'foo' - /'foo']; tight), fd=()-->(1)] │ ├── x:2 = '2ab23800-06b1-4e19-a3bb-df3768b808d2' [outer=(2), constraints=(/2: [/'2ab23800-06b1-4e19-a3bb-df3768b808d2' - /'2ab23800-06b1-4e19-a3bb-df3768b808d2']; tight), fd=()-->(2)] @@ -922,32 +922,32 @@ WHERE project ├── columns: attname:3!null atttypid:4!null typbasetype:51 typtype:33 ├── stats: [rows=198] - ├── cost: 2880.95877 + ├── cost: 2907.15877 └── inner-join (merge) ├── columns: attname:3!null atttypid:4!null oid:27!null typtype:33 typbasetype:51 ├── left ordering: +27 ├── right ordering: +4 ├── stats: [rows=198, distinct(4)=17.2927193, null(4)=0, distinct(27)=17.2927193, null(27)=0] - ├── cost: 2878.96877 + ├── cost: 2905.16877 ├── fd: (4)==(27), (27)==(4) ├── scan pg_type@secondary [as=t] │ ├── columns: oid:27!null typtype:33 typbasetype:51 │ ├── stats: [rows=1000, distinct(27)=100, null(27)=0] - │ ├── cost: 1467.51 + │ ├── cost: 1481.01 │ └── ordering: +27 ├── sort │ ├── columns: attname:3!null atttypid:4 │ ├── stats: [rows=20, distinct(3)=2, null(3)=0, distinct(4)=18.2927193, null(4)=0.2] - │ ├── cost: 1399.26877 + │ ├── cost: 1411.96877 │ ├── ordering: +4 │ └── select │ ├── columns: attname:3!null atttypid:4 │ ├── stats: [rows=20, distinct(3)=2, null(3)=0, distinct(4)=18.2927193, null(4)=0.2] - │ ├── cost: 1396.73 + │ ├── cost: 1409.43 │ ├── scan pg_attribute [as=a] │ │ ├── columns: attname:3 atttypid:4 │ │ ├── stats: [rows=1000, distinct(3)=100, null(3)=10, distinct(4)=100, null(4)=10] - │ │ └── cost: 1386.71 + │ │ └── cost: 1399.41 │ └── filters │ └── attname:3 IN ('descriptor_id', 'descriptor_name') [outer=(3), constraints=(/3: [/'descriptor_id' - /'descriptor_id'] [/'descriptor_name' - /'descriptor_name']; tight)] └── filters (true) @@ -970,23 +970,23 @@ WHERE project ├── columns: attname:3!null atttypid:4!null typbasetype:51 typtype:33 ├── stats: [rows=99] - ├── cost: 2831.38 + ├── cost: 2844.08 ├── fd: ()-->(3) └── inner-join (lookup pg_type@secondary [as=t]) ├── columns: attname:3!null atttypid:4!null oid:27!null typtype:33 typbasetype:51 ├── key columns: [4] = [27] ├── stats: [rows=99, distinct(4)=8.5617925, null(4)=0, distinct(27)=8.5617925, null(27)=0] - ├── cost: 2830.38 + ├── cost: 2843.08 ├── fd: ()-->(3), (4)==(27), (27)==(4) ├── select │ ├── columns: attname:3!null atttypid:4 │ ├── stats: [rows=10, distinct(3)=1, null(3)=0, distinct(4)=9.5617925, null(4)=0.1] - │ ├── cost: 1396.73 + │ ├── cost: 1409.43 │ ├── fd: ()-->(3) │ ├── scan pg_attribute [as=a] │ │ ├── columns: attname:3 atttypid:4 │ │ ├── stats: [rows=1000, distinct(3)=100, null(3)=10, distinct(4)=100, null(4)=10] - │ │ └── cost: 1386.71 + │ │ └── cost: 1399.41 │ └── filters │ └── attname:3 = 'descriptor_id' [outer=(3), constraints=(/3: [/'descriptor_id' - /'descriptor_id']; tight), fd=()-->(3)] └── filters (true) diff --git a/pkg/sql/opt/xform/testdata/coster/perturb-cost b/pkg/sql/opt/xform/testdata/coster/perturb-cost index 5ad1f0b71d02..19afe12058f0 100644 --- a/pkg/sql/opt/xform/testdata/coster/perturb-cost +++ b/pkg/sql/opt/xform/testdata/coster/perturb-cost @@ -22,7 +22,7 @@ SELECT * FROM a JOIN b ON a.x=b.x ORDER BY a.y sort ├── columns: x:1!null y:2 x:4!null ├── stats: [rows=1000, distinct(1)=1000, null(1)=0, distinct(4)=1000, null(4)=0] - ├── cost: 2377.96569 + ├── cost: 2398.56569 ├── key: (4) ├── fd: (1)-->(2), (1)==(4), (4)==(1) ├── ordering: +2 @@ -30,19 +30,19 @@ sort ├── columns: a.x:1!null y:2 b.x:4!null ├── multiplicity: left-rows(zero-or-one), right-rows(zero-or-one) ├── stats: [rows=1000, distinct(1)=1000, null(1)=0, distinct(4)=1000, null(4)=0] - ├── cost: 2128.64 + ├── cost: 2149.24 ├── key: (4) ├── fd: (1)-->(2), (1)==(4), (4)==(1) ├── scan a │ ├── columns: a.x:1!null y:2 │ ├── stats: [rows=1000, distinct(1)=1000, null(1)=0] - │ ├── cost: 1054.41 + │ ├── cost: 1064.81 │ ├── key: (1) │ └── fd: (1)-->(2) ├── scan b │ ├── columns: b.x:4!null │ ├── stats: [rows=1000, distinct(4)=1000, null(4)=0] - │ ├── cost: 1034.21 + │ ├── cost: 1044.41 │ └── key: (4) └── filters └── a.x:1 = b.x:4 [outer=(1,4), constraints=(/1: (/NULL - ]; /4: (/NULL - ]), fd=(1)==(4), (4)==(1)] diff --git a/pkg/sql/opt/xform/testdata/coster/project b/pkg/sql/opt/xform/testdata/coster/project index 031f508660e0..f27833120628 100644 --- a/pkg/sql/opt/xform/testdata/coster/project +++ b/pkg/sql/opt/xform/testdata/coster/project @@ -9,13 +9,13 @@ project ├── columns: k:1!null i:2 "?column?":6 ├── immutable ├── stats: [rows=1000] - ├── cost: 1104.72 + ├── cost: 1115.42 ├── key: (1) ├── fd: (1)-->(2,6) ├── scan a │ ├── columns: k:1!null i:2 s:3 │ ├── stats: [rows=1000] - │ ├── cost: 1084.71 + │ ├── cost: 1095.41 │ ├── key: (1) │ └── fd: (1)-->(2,3) └── projections @@ -28,13 +28,13 @@ project ├── columns: k:1!null "?column?":6!null "?column?":7 ├── immutable ├── stats: [rows=1000] - ├── cost: 1114.72 + ├── cost: 1125.42 ├── key: (1) ├── fd: (1)-->(6,7) ├── scan a │ ├── columns: k:1!null i:2 d:4!null │ ├── stats: [rows=1000] - │ ├── cost: 1084.71 + │ ├── cost: 1095.41 │ ├── key: (1) │ └── fd: (1)-->(2,4) └── projections diff --git a/pkg/sql/opt/xform/testdata/coster/scan b/pkg/sql/opt/xform/testdata/coster/scan index ec4d7f98f831..1552044e81c1 100644 --- a/pkg/sql/opt/xform/testdata/coster/scan +++ b/pkg/sql/opt/xform/testdata/coster/scan @@ -8,7 +8,7 @@ SELECT k, s FROM a scan a ├── columns: k:1!null s:3 ├── stats: [rows=1000] - ├── cost: 1074.61 + ├── cost: 1085.21 ├── key: (1) └── fd: (1)-->(3) @@ -111,7 +111,7 @@ SELECT * FROM a ORDER BY k DESC scan a,rev ├── columns: k:1!null i:2 s:3 d:4!null ├── stats: [rows=1] - ├── cost: 15.89 + ├── cost: 26.69 ├── key: (1) ├── fd: (1)-->(2-4) └── ordering: -1 @@ -150,7 +150,7 @@ select ├── cardinality: [0 - 2000] ├── immutable ├── stats: [rows=333.333333, distinct(1)=333.333333, null(1)=0] - ├── cost: 1034.03 + ├── cost: 1039.13 ├── key: (1) ├── scan speed_test │ ├── columns: id:1!null @@ -158,7 +158,7 @@ select │ ├── flags: force-index=primary │ ├── cardinality: [0 - 2000] │ ├── stats: [rows=1000, distinct(1)=1000, null(1)=0] - │ ├── cost: 1024.01 + │ ├── cost: 1029.11 │ └── key: (1) └── filters └── (id:1 % 16) = 0 [outer=(1), immutable] @@ -289,5 +289,160 @@ scan t60493 ├── stats: [rows=2, distinct(2)=2, null(2)=0] │ histogram(2)= 0 1 0 1 │ <--- 'useast' --- 'uswest' - ├── cost: 10.09 + ├── cost: 20.49 └── key: (1,2) + +# Regression test for #64570. Ensure we always prefer bounded over unbounded scans. +exec-ddl +CREATE TABLE t64570 (x INT, y INT, v INT, INDEX (y, v), PRIMARY KEY (x,y)) +---- + +# Inject stats corresponding to running: +# INSERT INTO t VALUES (1, 1, 1), (2, 2, 2), (3, 3, 3); +# +# These stats are important for the test below, which tries to search for +# the row (10, 10, 10). That row doesn't exist (and therefore doesn't show up +# in the histograms). +exec-ddl +ALTER TABLE t64570 INJECT STATISTICS '[ + { + "columns": [ + "x" + ], + "created_at": "2021-06-28 14:20:18.273949", + "distinct_count": 3, + "histo_buckets": [ + { + "distinct_range": 0, + "num_eq": 1, + "num_range": 0, + "upper_bound": "1" + }, + { + "distinct_range": 0, + "num_eq": 1, + "num_range": 0, + "upper_bound": "2" + }, + { + "distinct_range": 0, + "num_eq": 1, + "num_range": 0, + "upper_bound": "3" + } + ], + "histo_col_type": "INT8", + "name": "foo", + "null_count": 0, + "row_count": 3 + }, + { + "columns": [ + "y" + ], + "created_at": "2021-06-28 14:20:18.273949", + "distinct_count": 3, + "histo_buckets": [ + { + "distinct_range": 0, + "num_eq": 1, + "num_range": 0, + "upper_bound": "1" + }, + { + "distinct_range": 0, + "num_eq": 1, + "num_range": 0, + "upper_bound": "2" + }, + { + "distinct_range": 0, + "num_eq": 1, + "num_range": 0, + "upper_bound": "3" + } + ], + "histo_col_type": "INT8", + "name": "foo", + "null_count": 0, + "row_count": 3 + }, + { + "columns": [ + "v" + ], + "created_at": "2021-06-28 14:20:18.273949", + "distinct_count": 3, + "histo_buckets": [ + { + "distinct_range": 0, + "num_eq": 1, + "num_range": 0, + "upper_bound": "1" + }, + { + "distinct_range": 0, + "num_eq": 1, + "num_range": 0, + "upper_bound": "2" + }, + { + "distinct_range": 0, + "num_eq": 1, + "num_range": 0, + "upper_bound": "3" + } + ], + "histo_col_type": "INT8", + "name": "foo", + "null_count": 0, + "row_count": 3 + } +]' +---- + +# We should choose a constrained scan of the primary index with cardinality 1, +# not a constrained scan of the secondary index with unbounded cardinality. +opt +UPSERT INTO t64570 VALUES (10, 10, 10) +---- +upsert t64570 + ├── columns: + ├── arbiter indexes: primary + ├── canary column: x:8 + ├── fetch columns: x:8 y:9 v:10 + ├── insert-mapping: + │ ├── column1:5 => x:1 + │ ├── column2:6 => y:2 + │ └── column3:7 => v:3 + ├── update-mapping: + │ └── column3:7 => v:3 + ├── cardinality: [0 - 0] + ├── volatile, mutations + ├── stats: [rows=0] + ├── cost: 5.14883333 + └── left-join (cross) + ├── columns: column1:5!null column2:6!null column3:7!null x:8 y:9 v:10 + ├── cardinality: [1 - 1] + ├── multiplicity: left-rows(exactly-one), right-rows(exactly-one) + ├── stats: [rows=1] + ├── cost: 5.13883333 + ├── key: () + ├── fd: ()-->(5-10) + ├── values + │ ├── columns: column1:5!null column2:6!null column3:7!null + │ ├── cardinality: [1 - 1] + │ ├── stats: [rows=1] + │ ├── cost: 0.02 + │ ├── key: () + │ ├── fd: ()-->(5-7) + │ └── (10, 10, 10) + ├── scan t64570 + │ ├── columns: x:8!null y:9!null v:10 + │ ├── constraint: /8/9: [/10/10 - /10/10] + │ ├── cardinality: [0 - 1] + │ ├── stats: [rows=0.933333333, distinct(8)=0.933333333, null(8)=0, distinct(9)=0.933333333, null(9)=0, distinct(8,9)=0.933333333, null(8,9)=0] + │ ├── cost: 5.07 + │ ├── key: () + │ └── fd: ()-->(8-10) + └── filters (true) diff --git a/pkg/sql/opt/xform/testdata/coster/select b/pkg/sql/opt/xform/testdata/coster/select index a3e6075ab5a2..fac35ff09f25 100644 --- a/pkg/sql/opt/xform/testdata/coster/select +++ b/pkg/sql/opt/xform/testdata/coster/select @@ -8,13 +8,13 @@ SELECT k, s FROM a WHERE s >= 'foo' select ├── columns: k:1!null s:3!null ├── stats: [rows=333.333333, distinct(3)=33.3333333, null(3)=0] - ├── cost: 1084.63 + ├── cost: 1095.23 ├── key: (1) ├── fd: (1)-->(3) ├── scan a │ ├── columns: k:1!null s:3 │ ├── stats: [rows=1000, distinct(1)=1000, null(1)=0, distinct(3)=100, null(3)=10] - │ ├── cost: 1074.61 + │ ├── cost: 1085.21 │ ├── key: (1) │ └── fd: (1)-->(3) └── filters @@ -95,27 +95,27 @@ limit ├── columns: id:1!null ├── cardinality: [0 - 0] ├── stats: [rows=0] - ├── cost: 530014.55 + ├── cost: 530025.05 ├── key: (1) ├── project │ ├── columns: id:1!null │ ├── cardinality: [0 - 0] │ ├── stats: [rows=0] - │ ├── cost: 530014.54 + │ ├── cost: 530025.04 │ ├── key: (1) │ ├── limit hint: 10.00 │ └── select │ ├── columns: id:1!null geog:2 crdb_internal_mvcc_timestamp:3 │ ├── cardinality: [0 - 0] │ ├── stats: [rows=0] - │ ├── cost: 530014.53 + │ ├── cost: 530025.03 │ ├── key: (1) │ ├── fd: (1)-->(2,3) │ ├── limit hint: 10.00 │ ├── scan g │ │ ├── columns: id:1!null geog:2 crdb_internal_mvcc_timestamp:3 │ │ ├── stats: [rows=500000] - │ │ ├── cost: 525014.51 + │ │ ├── cost: 525025.01 │ │ ├── key: (1) │ │ └── fd: (1)-->(2,3) │ └── filters diff --git a/pkg/sql/opt/xform/testdata/coster/set b/pkg/sql/opt/xform/testdata/coster/set index f951487a9cb2..77dd64bbd93d 100644 --- a/pkg/sql/opt/xform/testdata/coster/set +++ b/pkg/sql/opt/xform/testdata/coster/set @@ -14,18 +14,18 @@ union ├── left columns: a.k:1 a.i:2 ├── right columns: x:6 z:7 ├── stats: [rows=2000, distinct(10,11)=2000, null(10,11)=0] - ├── cost: 2179.13 + ├── cost: 2200.23 ├── key: (10,11) ├── scan a │ ├── columns: a.k:1!null a.i:2 │ ├── stats: [rows=1000, distinct(1,2)=1000, null(1,2)=0] - │ ├── cost: 1074.61 + │ ├── cost: 1085.21 │ ├── key: (1) │ └── fd: (1)-->(2) └── scan b ├── columns: x:6 z:7!null ├── stats: [rows=1000, distinct(6,7)=1000, null(6,7)=0] - └── cost: 1064.51 + └── cost: 1075.01 opt SELECT k, i FROM a UNION ALL SELECT * FROM b @@ -35,17 +35,17 @@ union-all ├── left columns: a.k:1 a.i:2 ├── right columns: x:6 z:7 ├── stats: [rows=2000] - ├── cost: 2159.13 + ├── cost: 2180.23 ├── scan a │ ├── columns: a.k:1!null a.i:2 │ ├── stats: [rows=1000] - │ ├── cost: 1074.61 + │ ├── cost: 1085.21 │ ├── key: (1) │ └── fd: (1)-->(2) └── scan b ├── columns: x:6 z:7!null ├── stats: [rows=1000] - └── cost: 1064.51 + └── cost: 1075.01 opt SELECT k, i FROM a INTERSECT SELECT * FROM b @@ -55,18 +55,18 @@ intersect ├── left columns: k:1 i:2 ├── right columns: x:6 z:7 ├── stats: [rows=1000, distinct(1,2)=1000, null(1,2)=0] - ├── cost: 2169.13 + ├── cost: 2190.23 ├── key: (1,2) ├── scan a │ ├── columns: k:1!null i:2 │ ├── stats: [rows=1000, distinct(1,2)=1000, null(1,2)=0] - │ ├── cost: 1074.61 + │ ├── cost: 1085.21 │ ├── key: (1) │ └── fd: (1)-->(2) └── scan b ├── columns: x:6 z:7!null ├── stats: [rows=1000, distinct(6,7)=1000, null(6,7)=0] - └── cost: 1064.51 + └── cost: 1075.01 opt SELECT k, i FROM a INTERSECT ALL SELECT * FROM b @@ -76,17 +76,17 @@ intersect-all ├── left columns: k:1 i:2 ├── right columns: x:6 z:7 ├── stats: [rows=1000] - ├── cost: 2169.13 + ├── cost: 2190.23 ├── scan a │ ├── columns: k:1!null i:2 │ ├── stats: [rows=1000] - │ ├── cost: 1074.61 + │ ├── cost: 1085.21 │ ├── key: (1) │ └── fd: (1)-->(2) └── scan b ├── columns: x:6 z:7!null ├── stats: [rows=1000] - └── cost: 1064.51 + └── cost: 1075.01 opt SELECT k, i FROM a EXCEPT SELECT * FROM b @@ -96,18 +96,18 @@ except ├── left columns: k:1 i:2 ├── right columns: x:6 z:7 ├── stats: [rows=1000, distinct(1,2)=1000, null(1,2)=0] - ├── cost: 2169.13 + ├── cost: 2190.23 ├── key: (1,2) ├── scan a │ ├── columns: k:1!null i:2 │ ├── stats: [rows=1000, distinct(1,2)=1000, null(1,2)=0] - │ ├── cost: 1074.61 + │ ├── cost: 1085.21 │ ├── key: (1) │ └── fd: (1)-->(2) └── scan b ├── columns: x:6 z:7!null ├── stats: [rows=1000, distinct(6,7)=1000, null(6,7)=0] - └── cost: 1064.51 + └── cost: 1075.01 opt SELECT k, i FROM a EXCEPT ALL SELECT * FROM b @@ -117,14 +117,14 @@ except-all ├── left columns: k:1 i:2 ├── right columns: x:6 z:7 ├── stats: [rows=1000] - ├── cost: 2169.13 + ├── cost: 2190.23 ├── scan a │ ├── columns: k:1!null i:2 │ ├── stats: [rows=1000] - │ ├── cost: 1074.61 + │ ├── cost: 1085.21 │ ├── key: (1) │ └── fd: (1)-->(2) └── scan b ├── columns: x:6 z:7!null ├── stats: [rows=1000] - └── cost: 1064.51 + └── cost: 1075.01 diff --git a/pkg/sql/opt/xform/testdata/coster/sort b/pkg/sql/opt/xform/testdata/coster/sort index 38570afeb9b1..a736685f688a 100644 --- a/pkg/sql/opt/xform/testdata/coster/sort +++ b/pkg/sql/opt/xform/testdata/coster/sort @@ -15,12 +15,12 @@ SELECT f FROM a ORDER BY f DESC sort ├── columns: f:2!null ├── stats: [rows=1000] - ├── cost: 1293.83569 + ├── cost: 1304.33569 ├── ordering: -2 └── scan a ├── columns: f:2!null ├── stats: [rows=1000] - └── cost: 1064.51 + └── cost: 1075.01 # Test sort on 0 rows. opt @@ -53,12 +53,12 @@ SELECT * FROM abc ORDER BY b, c, a sort ├── columns: a:1 b:2 c:3 ├── stats: [rows=1000] - ├── cost: 1346.09805 + ├── cost: 1356.79805 ├── ordering: +2,+3,+1 └── scan abc ├── columns: a:1 b:2 c:3 ├── stats: [rows=1000] - └── cost: 1084.71 + └── cost: 1095.41 # The sort ordering has a common prefix with the ordering provided with index ab opt @@ -67,12 +67,12 @@ SELECT * FROM abc ORDER BY a, b, c sort (segmented) ├── columns: a:1 b:2 c:3 ├── stats: [rows=1000, distinct(1,2)=1000, null(1,2)=0.1] - ├── cost: 1154.72 + ├── cost: 1165.42 ├── ordering: +1,+2,+3 └── scan abc@ab ├── columns: a:1 b:2 c:3 ├── stats: [rows=1000, distinct(1,2)=1000, null(1,2)=0.1] - ├── cost: 1084.71 + ├── cost: 1095.41 └── ordering: +1,+2 # The sort ordering has a common prefix with the ordering provided with index cb @@ -82,12 +82,12 @@ SELECT * FROM abc ORDER BY c, b, a sort (segmented) ├── columns: a:1 b:2 c:3 ├── stats: [rows=1000, distinct(2,3)=1000, null(2,3)=0.1] - ├── cost: 1154.72 + ├── cost: 1165.42 ├── ordering: +3,+2,+1 └── scan abc@cb ├── columns: a:1 b:2 c:3 ├── stats: [rows=1000, distinct(2,3)=1000, null(2,3)=0.1] - ├── cost: 1084.71 + ├── cost: 1095.41 └── ordering: +3,+2 # Testing segmented sort cost with only one common prefix column (c). @@ -97,12 +97,12 @@ SELECT * FROM abc ORDER BY c, a, b sort (segmented) ├── columns: a:1 b:2 c:3 ├── stats: [rows=1000, distinct(3)=100, null(3)=10] - ├── cost: 1215.48049 + ├── cost: 1226.18049 ├── ordering: +3,+1,+2 └── scan abc@cb ├── columns: a:1 b:2 c:3 ├── stats: [rows=1000, distinct(3)=100, null(3)=10] - ├── cost: 1084.71 + ├── cost: 1095.41 └── ordering: +3 # Reduce the number of segments/chunks. @@ -130,12 +130,12 @@ SELECT * FROM abc ORDER BY a, b, c sort (segmented) ├── columns: a:1 b:2 c:3 ├── stats: [rows=10000, distinct(1,2)=10, null(1,2)=0] - ├── cost: 13407.8769 + ├── cost: 13418.5769 ├── ordering: +1,+2,+3 └── scan abc@ab ├── columns: a:1 b:2 c:3 ├── stats: [rows=10000, distinct(1,2)=10, null(1,2)=0] - ├── cost: 10714.71 + ├── cost: 10725.41 └── ordering: +1,+2 # Segmented sort should still be chosen with if equality columns help provide the required ordering. @@ -145,20 +145,20 @@ SELECT * FROM abc WHERE a = b ORDER BY b, a, c sort (segmented) ├── columns: a:1!null b:2!null c:3 ├── stats: [rows=2000, distinct(1)=2, null(1)=0, distinct(2)=2, null(2)=0] - ├── cost: 11322.6714 + ├── cost: 11333.3714 ├── fd: (1)==(2), (2)==(1) ├── ordering: +(1|2),+3 [actual: +1,+3] └── select ├── columns: a:1!null b:2!null c:3 ├── stats: [rows=2000, distinct(1)=2, null(1)=0, distinct(2)=2, null(2)=0] - ├── cost: 10804.03 + ├── cost: 10814.73 ├── fd: (1)==(2), (2)==(1) ├── ordering: +1 ├── scan abc@ab │ ├── columns: a:1!null b:2 c:3 │ ├── constraint: /1/2/4: (/NULL - ] │ ├── stats: [rows=10000, distinct(1)=5, null(1)=0] - │ ├── cost: 10704.01 + │ ├── cost: 10714.71 │ └── ordering: +1 └── filters └── a:1 = b:2 [outer=(1,2), constraints=(/1: (/NULL - ]; /2: (/NULL - ]), fd=(1)==(2), (2)==(1)] diff --git a/pkg/sql/opt/xform/testdata/coster/virtual-scan b/pkg/sql/opt/xform/testdata/coster/virtual-scan index b1bac9390d44..855b9d855e6c 100644 --- a/pkg/sql/opt/xform/testdata/coster/virtual-scan +++ b/pkg/sql/opt/xform/testdata/coster/virtual-scan @@ -4,11 +4,11 @@ SELECT * FROM information_schema.schemata WHERE SCHEMA_NAME='public' select ├── columns: catalog_name:2!null schema_name:3!null default_character_set_name:4 sql_path:5 crdb_is_user_defined:6 ├── stats: [rows=10, distinct(3)=1, null(3)=0] - ├── cost: 1235.13 + ├── cost: 1246.23 ├── fd: ()-->(3) ├── scan schemata │ ├── columns: catalog_name:2!null schema_name:3!null default_character_set_name:4 sql_path:5 crdb_is_user_defined:6 │ ├── stats: [rows=1000, distinct(2)=100, null(2)=0, distinct(3)=100, null(3)=0] - │ └── cost: 1225.11 + │ └── cost: 1236.21 └── filters └── schema_name:3 = 'public' [outer=(3), constraints=(/3: [/'public' - /'public']; tight), fd=()-->(3)] diff --git a/pkg/sql/opt/xform/testdata/coster/zone b/pkg/sql/opt/xform/testdata/coster/zone index edccd35a67aa..6c2e92413c6e 100644 --- a/pkg/sql/opt/xform/testdata/coster/zone +++ b/pkg/sql/opt/xform/testdata/coster/zone @@ -40,7 +40,7 @@ SELECT * FROM abc scan t.public.abc ├── columns: a:1(int!null) b:2(int) c:3(string) ├── stats: [rows=1000] - ├── cost: 1074.61 + ├── cost: 1085.21 ├── key: (1) ├── fd: (1)-->(2,3), (2,3)~~>(1) ├── prune: (1-3) @@ -54,7 +54,7 @@ scan t.public.abc@bc1 ├── columns: a:1(int!null) b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 15.21 + ├── cost: 26.41 ├── key: (1) ├── fd: ()-->(2), (1)-->(3), (2,3)~~>(1) ├── prune: (1,3) @@ -68,7 +68,7 @@ scan t.public.abc@bc1 ├── columns: b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 14.51 + ├── cost: 25.01 ├── lax-key: (3) ├── fd: ()-->(2) ├── prune: (3) @@ -82,7 +82,7 @@ scan t.public.abc@bc2 ├── columns: b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 14.51 + ├── cost: 25.01 ├── lax-key: (3) ├── fd: ()-->(2) ├── prune: (3) @@ -96,7 +96,7 @@ scan t.public.abc@bc1 ├── columns: b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 14.51 + ├── cost: 25.01 ├── lax-key: (3) ├── fd: ()-->(2) ├── prune: (3) @@ -110,7 +110,7 @@ scan t.public.abc@bc1 ├── columns: b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 15.01 + ├── cost: 26.01 ├── lax-key: (3) ├── fd: ()-->(2) ├── prune: (3) @@ -140,7 +140,7 @@ SELECT * FROM abc scan t.public.abc ├── columns: a:1(int!null) b:2(int) c:3(string) ├── stats: [rows=1000] - ├── cost: 1074.61 + ├── cost: 1085.21 ├── key: (1) ├── fd: (1)-->(2,3), (2,3)~~>(1) ├── prune: (1-3) @@ -154,7 +154,7 @@ scan t.public.abc@bc1 ├── columns: b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 14.76 + ├── cost: 25.51 ├── lax-key: (3) ├── fd: ()-->(2) ├── prune: (3) @@ -168,7 +168,7 @@ scan t.public.abc@bc1 ├── columns: b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 14.51 + ├── cost: 25.01 ├── lax-key: (3) ├── fd: ()-->(2) ├── prune: (3) @@ -183,7 +183,7 @@ scan t.public.abc@bc2 ├── columns: b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 14.51 + ├── cost: 25.01 ├── lax-key: (3) ├── fd: ()-->(2) ├── prune: (3) @@ -210,7 +210,7 @@ scan t.public.abc@bc1 ├── columns: b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 14.51 + ├── cost: 25.01 ├── lax-key: (3) ├── fd: ()-->(2) ├── prune: (3) @@ -225,7 +225,7 @@ scan t.public.abc@bc2 ├── columns: b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 14.51 + ├── cost: 25.01 ├── lax-key: (3) ├── fd: ()-->(2) ├── prune: (3) @@ -251,7 +251,7 @@ scan t.public.abc@bc1 ├── columns: b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 14.51 + ├── cost: 25.01 ├── lax-key: (3) ├── fd: ()-->(2) ├── prune: (3) @@ -265,7 +265,7 @@ scan t.public.abc@bc2 ├── columns: b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 14.51 + ├── cost: 25.01 ├── lax-key: (3) ├── fd: ()-->(2) ├── prune: (3) @@ -280,7 +280,7 @@ scan t.public.abc@bc2 ├── columns: b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 14.51 + ├── cost: 25.01 ├── lax-key: (3) ├── fd: ()-->(2) ├── prune: (3) @@ -295,7 +295,7 @@ scan t.public.abc@bc1 ├── columns: b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 14.76 + ├── cost: 25.51 ├── lax-key: (3) ├── fd: ()-->(2) ├── prune: (3) @@ -317,7 +317,7 @@ scan t.public.abc@bc1 ├── columns: b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 14.51 + ├── cost: 25.01 ├── lax-key: (3) ├── fd: ()-->(2) ├── prune: (3) @@ -331,7 +331,7 @@ scan t.public.abc@bc2 ├── columns: b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 14.51 + ├── cost: 25.01 ├── lax-key: (3) ├── fd: ()-->(2) ├── prune: (3) @@ -367,7 +367,7 @@ inner-join (lookup t.public.xy@y2) ├── flags: force lookup join (into right side) ├── key columns: [2] = [6] ├── stats: [rows=100, distinct(2)=1, null(2)=0, distinct(6)=1, null(6)=0] - ├── cost: 417.58 + ├── cost: 428.18 ├── key: (1,5) ├── fd: ()-->(2,6), (1)-->(3), (2,3)~~>(1), (2)==(6), (6)==(2) ├── prune: (1,3,5) @@ -376,7 +376,7 @@ inner-join (lookup t.public.xy@y2) │ ├── columns: t.public.abc.a:1(int!null) t.public.abc.b:2(int!null) t.public.abc.c:3(string) │ ├── constraint: /2/3: [/1 - /1] │ ├── stats: [rows=10, distinct(1)=10, null(1)=0, distinct(2)=1, null(2)=0] - │ ├── cost: 14.61 + │ ├── cost: 25.21 │ ├── key: (1) │ ├── fd: ()-->(2), (1)-->(3), (2,3)~~>(1) │ ├── prune: (1,3) @@ -405,7 +405,7 @@ inner-join (lookup t.public.xy@y1) ├── flags: force lookup join (into right side) ├── key columns: [2] = [6] ├── stats: [rows=100, distinct(2)=1, null(2)=0, distinct(6)=1, null(6)=0] - ├── cost: 417.58 + ├── cost: 428.18 ├── key: (1,5) ├── fd: ()-->(2,6), (1)-->(3), (2,3)~~>(1), (2)==(6), (6)==(2) ├── prune: (1,3,5) @@ -414,7 +414,7 @@ inner-join (lookup t.public.xy@y1) │ ├── columns: t.public.abc.a:1(int!null) t.public.abc.b:2(int!null) t.public.abc.c:3(string) │ ├── constraint: /2/3: [/1 - /1] │ ├── stats: [rows=10, distinct(1)=10, null(1)=0, distinct(2)=1, null(2)=0] - │ ├── cost: 14.61 + │ ├── cost: 25.21 │ ├── key: (1) │ ├── fd: ()-->(2), (1)-->(3), (2,3)~~>(1) │ ├── prune: (1,3) @@ -447,7 +447,7 @@ SELECT * FROM abc scan t.public.abc ├── columns: a:1(int!null) b:2(int) c:3(string) ├── stats: [rows=1000] - ├── cost: 1115.01 + ├── cost: 1126.01 ├── key: (1) ├── fd: (1)-->(2,3), (2,3)~~>(1) ├── prune: (1-3) @@ -461,7 +461,7 @@ scan t.public.abc@bc1 ├── columns: b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 15.01 + ├── cost: 26.01 ├── lax-key: (3) ├── fd: ()-->(2) ├── prune: (3) @@ -475,7 +475,7 @@ scan t.public.abc@bc1 ├── columns: b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 14.8433333 + ├── cost: 25.6766667 ├── lax-key: (3) ├── fd: ()-->(2) ├── prune: (3) @@ -489,7 +489,7 @@ scan t.public.abc@bc2 ├── columns: b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 14.8433333 + ├── cost: 25.6766667 ├── lax-key: (3) ├── fd: ()-->(2) ├── prune: (3) @@ -518,7 +518,7 @@ SELECT * FROM abc scan t.public.abc ├── columns: a:1(int!null) b:2(int) c:3(string) ├── stats: [rows=1000] - ├── cost: 1115.01 + ├── cost: 1126.01 ├── key: (1) ├── fd: (1)-->(2,3), (2,3)~~>(1) ├── prune: (1-3) @@ -532,7 +532,7 @@ scan t.public.abc@bc1 ├── columns: b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 14.9266667 + ├── cost: 25.8433333 ├── lax-key: (3) ├── fd: ()-->(2) ├── prune: (3) @@ -546,7 +546,7 @@ scan t.public.abc@bc1 ├── columns: b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 14.8433333 + ├── cost: 25.6766667 ├── lax-key: (3) ├── fd: ()-->(2) ├── prune: (3) @@ -560,7 +560,7 @@ scan t.public.abc@bc2 ├── columns: b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 14.8433333 + ├── cost: 25.6766667 ├── lax-key: (3) ├── fd: ()-->(2) ├── prune: (3) @@ -592,7 +592,7 @@ SELECT * FROM abc scan t.public.abc ├── columns: a:1(int!null) b:2(int) c:3(string) ├── stats: [rows=1000] - ├── cost: 1094.81 + ├── cost: 1105.61 ├── key: (1) ├── fd: (1)-->(2,3), (2,3)~~>(1) ├── prune: (1-3) @@ -606,7 +606,7 @@ scan t.public.abc@bc1 ├── columns: b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 14.76 + ├── cost: 25.51 ├── lax-key: (3) ├── fd: ()-->(2) ├── prune: (3) @@ -620,7 +620,7 @@ scan t.public.abc@bc1 ├── columns: b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 14.6766667 + ├── cost: 25.3433333 ├── lax-key: (3) ├── fd: ()-->(2) ├── prune: (3) @@ -634,7 +634,7 @@ scan t.public.abc@bc2 ├── columns: b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 14.6766667 + ├── cost: 25.3433333 ├── lax-key: (3) ├── fd: ()-->(2) ├── prune: (3) @@ -663,7 +663,7 @@ scan t.public.abc@bc2 ├── columns: b:2(int!null) c:3(string) ├── constraint: /2/3: [/10 - /10] ├── stats: [rows=10, distinct(2)=1, null(2)=0] - ├── cost: 14.51 + ├── cost: 25.01 ├── lax-key: (3) ├── fd: ()-->(2) ├── prune: (3) @@ -715,7 +715,7 @@ locality-optimized-search ├── right columns: t.public.abc_part.r:11(string) t.public.abc_part.a:12(int) t.public.abc_part.b:13(int) t.public.abc_part.c:14(string) ├── cardinality: [0 - 1] ├── stats: [rows=0.910000001, distinct(3)=0.910000001, null(3)=0, distinct(4)=0.910000001, null(4)=0, distinct(3,4)=0.910000001, null(3,4)=0] - ├── cost: 3.401844 + ├── cost: 3.4791 ├── key: () ├── fd: ()-->(1-4) ├── prune: (1,2) @@ -725,7 +725,7 @@ locality-optimized-search │ ├── constraint: /6/8/9: [/'east'/1/'foo' - /'east'/1/'foo'] │ ├── cardinality: [0 - 1] │ ├── stats: [rows=0.9001, distinct(6)=0.9001, null(6)=0, distinct(8)=0.9001, null(8)=0, distinct(9)=0.9001, null(9)=0, distinct(6,8,9)=0.9001, null(6,8,9)=0] - │ ├── cost: 1.691372 + │ ├── cost: 1.73 │ ├── key: () │ ├── fd: ()-->(6-9) │ ├── prune: (6-9) @@ -735,7 +735,7 @@ locality-optimized-search ├── constraint: /11/13/14: [/'west'/1/'foo' - /'west'/1/'foo'] ├── cardinality: [0 - 1] ├── stats: [rows=0.9001, distinct(11)=0.9001, null(11)=0, distinct(13)=0.9001, null(13)=0, distinct(14)=0.9001, null(14)=0, distinct(11,13,14)=0.9001, null(11,13,14)=0] - ├── cost: 1.691372 + ├── cost: 1.73 ├── key: () ├── fd: ()-->(11-14) ├── prune: (11-14) @@ -755,7 +755,7 @@ anti-join (lookup abc_part@bc_idx [as=a2]) │ └── a2.r:6 = 'west' [outer=(6), constraints=(/6: [/'west' - /'west']; tight), fd=()-->(6)] ├── cardinality: [0 - 1] ├── stats: [rows=1e-10] - ├── cost: 18.0617898 + ├── cost: 18.1390458 ├── key: () ├── fd: ()-->(1-4) ├── anti-join (lookup abc_part@bc_idx [as=a2]) @@ -766,7 +766,7 @@ anti-join (lookup abc_part@bc_idx [as=a2]) │ │ └── a2.r:6 = 'east' [outer=(6), constraints=(/6: [/'east' - /'east']; tight), fd=()-->(6)] │ ├── cardinality: [0 - 1] │ ├── stats: [rows=0.900900001, distinct(1)=0.89738934, null(1)=0, distinct(2)=0.900900001, null(2)=0, distinct(3)=0.900900001, null(3)=0, distinct(4)=0.900900001, null(4)=0] - │ ├── cost: 10.7686007 + │ ├── cost: 10.8458567 │ ├── key: () │ ├── fd: ()-->(1-4) │ ├── locality-optimized-search @@ -775,7 +775,7 @@ anti-join (lookup abc_part@bc_idx [as=a2]) │ │ ├── right columns: a1.r:16 a1.a:17 a1.b:18 a1.c:19 │ │ ├── cardinality: [0 - 1] │ │ ├── stats: [rows=0.910000001, distinct(1)=0.906282579, null(1)=0, distinct(2)=0.910000001, null(2)=0, distinct(3)=0.910000001, null(3)=0, distinct(4)=0.910000001, null(4)=0, distinct(3,4)=0.910000001, null(3,4)=0] - │ │ ├── cost: 3.401844 + │ │ ├── cost: 3.4791 │ │ ├── key: () │ │ ├── fd: ()-->(1-4) │ │ ├── scan abc_part@bc_idx [as=a1] @@ -783,7 +783,7 @@ anti-join (lookup abc_part@bc_idx [as=a2]) │ │ │ ├── constraint: /11/13/14: [/'east'/1/'foo' - /'east'/1/'foo'] │ │ │ ├── cardinality: [0 - 1] │ │ │ ├── stats: [rows=0.9001, distinct(11)=0.9001, null(11)=0, distinct(13)=0.9001, null(13)=0, distinct(14)=0.9001, null(14)=0, distinct(11,13,14)=0.9001, null(11,13,14)=0] - │ │ │ ├── cost: 1.691372 + │ │ │ ├── cost: 1.73 │ │ │ ├── key: () │ │ │ └── fd: ()-->(11-14) │ │ └── scan abc_part@bc_idx [as=a1] @@ -791,7 +791,7 @@ anti-join (lookup abc_part@bc_idx [as=a2]) │ │ ├── constraint: /16/18/19: [/'west'/1/'foo' - /'west'/1/'foo'] │ │ ├── cardinality: [0 - 1] │ │ ├── stats: [rows=0.9001, distinct(16)=0.9001, null(16)=0, distinct(18)=0.9001, null(18)=0, distinct(19)=0.9001, null(19)=0, distinct(16,18,19)=0.9001, null(16,18,19)=0] - │ │ ├── cost: 1.691372 + │ │ ├── cost: 1.73 │ │ ├── key: () │ │ └── fd: ()-->(16-19) │ └── filters (true) diff --git a/pkg/sql/opt/xform/testdata/physprops/ordering b/pkg/sql/opt/xform/testdata/physprops/ordering index 5aedf0e7420d..dfde5f397a31 100644 --- a/pkg/sql/opt/xform/testdata/physprops/ordering +++ b/pkg/sql/opt/xform/testdata/physprops/ordering @@ -272,25 +272,25 @@ memo (optimized, ~5KB, required=[presentation: y:2,z:6] [ordering: +1,-2]) ├── G1: (project G2 G3 x y) │ ├── [presentation: y:2,z:6] [ordering: +1,-2] │ │ ├── best: (project G2="[ordering: +1,-2]" G3 x y) - │ │ └── cost: 1091.31 + │ │ └── cost: 1101.91 │ └── [] │ ├── best: (project G2 G3 x y) - │ └── cost: 1091.31 + │ └── cost: 1101.91 ├── G2: (select G4 G5) │ ├── [ordering: +1,-2] │ │ ├── best: (select G4="[ordering: +1,-2]" G5) - │ │ └── cost: 1084.63 + │ │ └── cost: 1095.23 │ └── [] │ ├── best: (select G4 G5) - │ └── cost: 1084.63 + │ └── cost: 1095.23 ├── G3: (projections G6) ├── G4: (scan a,cols=(1,2)) │ ├── [ordering: +1,-2] │ │ ├── best: (scan a,cols=(1,2)) - │ │ └── cost: 1074.61 + │ │ └── cost: 1085.21 │ └── [] │ ├── best: (scan a,cols=(1,2)) - │ └── cost: 1074.61 + │ └── cost: 1085.21 ├── G5: (filters G7) ├── G6: (minus G8 G9) ├── G7: (gt G8 G10) @@ -325,25 +325,25 @@ memo (optimized, ~5KB, required=[presentation: y:2,z:3] [ordering: +2]) ├── G1: (project G2 G3 y z) │ ├── [presentation: y:2,z:3] [ordering: +2] │ │ ├── best: (sort G1) - │ │ └── cost: 1167.29 + │ │ └── cost: 1177.99 │ └── [] │ ├── best: (project G2 G3 y z) - │ └── cost: 1098.07 + │ └── cost: 1108.77 ├── G2: (select G4 G5) │ ├── [ordering: +2] │ │ ├── best: (sort G2) - │ │ └── cost: 1167.28 + │ │ └── cost: 1177.98 │ └── [] │ ├── best: (select G4 G5) - │ └── cost: 1094.73 + │ └── cost: 1105.43 ├── G3: (projections) ├── G4: (scan a,cols=(1-3)) │ ├── [ordering: +2] │ │ ├── best: (sort G4) - │ │ └── cost: 1334.04 + │ │ └── cost: 1344.74 │ └── [] │ ├── best: (scan a,cols=(1-3)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G5: (filters G6) ├── G6: (gt G7 G8) ├── G7: (variable x) @@ -640,14 +640,14 @@ memo (optimized, ~3KB, required=[presentation: info:6]) ├── G1: (explain G2 [presentation: x:1,y:2,z:3,s:4] [ordering: +2]) │ └── [presentation: info:6] │ ├── best: (explain G2="[presentation: x:1,y:2,z:3,s:4] [ordering: +2]" [presentation: x:1,y:2,z:3,s:4] [ordering: +2]) - │ └── cost: 1354.15 + │ └── cost: 1364.95 └── G2: (scan a,cols=(1-4)) ├── [presentation: x:1,y:2,z:3,s:4] [ordering: +2] │ ├── best: (sort G2) - │ └── cost: 1354.14 + │ └── cost: 1364.94 └── [] ├── best: (scan a,cols=(1-4)) - └── cost: 1094.81 + └── cost: 1105.61 # -------------------------------------------------- # With Ordinality @@ -660,14 +660,14 @@ memo (optimized, ~4KB, required=[presentation: y:2] [ordering: +6]) ├── G1: (ordinality G2) │ ├── [presentation: y:2] [ordering: +6] │ │ ├── best: (ordinality G2) - │ │ └── cost: 1074.52 + │ │ └── cost: 1085.02 │ └── [] │ ├── best: (ordinality G2) - │ └── cost: 1074.52 + │ └── cost: 1085.02 └── G2: (scan a,cols=(2)) └── [] ├── best: (scan a,cols=(2)) - └── cost: 1064.51 + └── cost: 1075.01 memo SELECT y FROM a WITH ORDINALITY ORDER BY -ordinality @@ -676,19 +676,19 @@ memo (optimized, ~5KB, required=[presentation: y:2] [ordering: +7]) ├── G1: (project G2 G3 y) │ ├── [presentation: y:2] [ordering: +7] │ │ ├── best: (sort G1) - │ │ └── cost: 1333.86 + │ │ └── cost: 1344.36 │ └── [] │ ├── best: (project G2 G3 y) - │ └── cost: 1094.53 + │ └── cost: 1105.03 ├── G2: (ordinality G4) │ └── [] │ ├── best: (ordinality G4) - │ └── cost: 1074.52 + │ └── cost: 1085.02 ├── G3: (projections G5) ├── G4: (scan a,cols=(2)) │ └── [] │ ├── best: (scan a,cols=(2)) - │ └── cost: 1064.51 + │ └── cost: 1075.01 ├── G5: (unary-minus G6) └── G6: (variable ordinality) @@ -699,14 +699,14 @@ memo (optimized, ~6KB, required=[presentation: y:2] [ordering: +6]) ├── G1: (ordinality G2) │ ├── [presentation: y:2] [ordering: +6] │ │ ├── best: (ordinality G2) - │ │ └── cost: 1074.52 + │ │ └── cost: 1085.02 │ └── [] │ ├── best: (ordinality G2) - │ └── cost: 1074.52 + │ └── cost: 1085.02 └── G2: (scan a,cols=(2)) └── [] ├── best: (scan a,cols=(2)) - └── cost: 1064.51 + └── cost: 1075.01 memo SELECT y FROM (SELECT * FROM a ORDER BY y) WITH ORDINALITY ORDER BY y, ordinality @@ -715,17 +715,17 @@ memo (optimized, ~5KB, required=[presentation: y:2] [ordering: +2,+6]) ├── G1: (ordinality G2 ordering=+2) │ ├── [presentation: y:2] [ordering: +2,+6] │ │ ├── best: (ordinality G2="[ordering: +2]" ordering=+2) - │ │ └── cost: 1303.85 + │ │ └── cost: 1314.35 │ └── [] │ ├── best: (ordinality G2="[ordering: +2]" ordering=+2) - │ └── cost: 1303.85 + │ └── cost: 1314.35 └── G2: (scan a,cols=(2)) ├── [ordering: +2] │ ├── best: (sort G2) - │ └── cost: 1293.84 + │ └── cost: 1304.34 └── [] ├── best: (scan a,cols=(2)) - └── cost: 1064.51 + └── cost: 1075.01 memo SELECT y FROM (SELECT * FROM a ORDER BY y) WITH ORDINALITY ORDER BY ordinality, y @@ -734,17 +734,17 @@ memo (optimized, ~5KB, required=[presentation: y:2] [ordering: +6]) ├── G1: (ordinality G2 ordering=+2) │ ├── [presentation: y:2] [ordering: +6] │ │ ├── best: (ordinality G2="[ordering: +2]" ordering=+2) - │ │ └── cost: 1303.85 + │ │ └── cost: 1314.35 │ └── [] │ ├── best: (ordinality G2="[ordering: +2]" ordering=+2) - │ └── cost: 1303.85 + │ └── cost: 1314.35 └── G2: (scan a,cols=(2)) ├── [ordering: +2] │ ├── best: (sort G2) - │ └── cost: 1293.84 + │ └── cost: 1304.34 └── [] ├── best: (scan a,cols=(2)) - └── cost: 1064.51 + └── cost: 1075.01 memo SELECT y FROM a WITH ORDINALITY ORDER BY ordinality DESC @@ -753,14 +753,14 @@ memo (optimized, ~4KB, required=[presentation: y:2] [ordering: -6]) ├── G1: (ordinality G2) │ ├── [presentation: y:2] [ordering: -6] │ │ ├── best: (sort G1) - │ │ └── cost: 1313.85 + │ │ └── cost: 1324.35 │ └── [] │ ├── best: (ordinality G2) - │ └── cost: 1074.52 + │ └── cost: 1085.02 └── G2: (scan a,cols=(2)) └── [] ├── best: (scan a,cols=(2)) - └── cost: 1064.51 + └── cost: 1075.01 # -------------------------------------------------- # Merge Join diff --git a/pkg/sql/opt/xform/testdata/rules/groupby b/pkg/sql/opt/xform/testdata/rules/groupby index f371988e6ba5..82f214eecf04 100644 --- a/pkg/sql/opt/xform/testdata/rules/groupby +++ b/pkg/sql/opt/xform/testdata/rules/groupby @@ -501,7 +501,7 @@ memo (optimized, ~5KB, required=[presentation: min:6]) │ │ └── cost: 5.06 │ └── [] │ ├── best: (scan abc,cols=(1)) - │ └── cost: 1064.51 + │ └── cost: 1075.01 ├── G3: (aggregations G6) ├── G4: (limit G2 G7 ordering=+1) (scan abc,cols=(1),lim=1) │ └── [] @@ -520,28 +520,28 @@ memo (optimized, ~6KB, required=[presentation: min:6]) ├── G1: (scalar-group-by G2 G3 cols=()) (scalar-group-by G4 G5 cols=()) │ └── [presentation: min:6] │ ├── best: (scalar-group-by G2 G3 cols=()) - │ └── cost: 1074.54 + │ └── cost: 1085.04 ├── G2: (scan abc,cols=(2)) │ ├── [ordering: +2] [limit hint: 1.01] │ │ ├── best: (sort G2) - │ │ └── cost: 1293.84 + │ │ └── cost: 1304.34 │ └── [] │ ├── best: (scan abc,cols=(2)) - │ └── cost: 1064.51 + │ └── cost: 1075.01 ├── G3: (aggregations G6) ├── G4: (limit G7 G8 ordering=+2) │ └── [] │ ├── best: (limit G7="[ordering: +2] [limit hint: 1.00]" G8 ordering=+2) - │ └── cost: 1293.89 + │ └── cost: 1304.39 ├── G5: (aggregations G9) ├── G6: (min G10) ├── G7: (select G2 G11) │ ├── [ordering: +2] [limit hint: 1.00] │ │ ├── best: (select G2="[ordering: +2] [limit hint: 1.01]" G11) - │ │ └── cost: 1293.87 + │ │ └── cost: 1304.37 │ └── [] │ ├── best: (select G2 G11) - │ └── cost: 1074.53 + │ └── cost: 1085.03 ├── G8: (const 1) ├── G9: (const-agg G10) ├── G10: (variable b) @@ -563,7 +563,7 @@ memo (optimized, ~5KB, required=[presentation: max:6]) │ │ └── cost: 5.16 │ └── [] │ ├── best: (scan abc,cols=(1)) - │ └── cost: 1064.51 + │ └── cost: 1075.01 ├── G3: (aggregations G6) ├── G4: (limit G2 G7 ordering=-1) (scan abc,rev,cols=(1),lim=1(rev)) │ └── [] @@ -582,28 +582,28 @@ memo (optimized, ~6KB, required=[presentation: max:6]) ├── G1: (scalar-group-by G2 G3 cols=()) (scalar-group-by G4 G5 cols=()) │ └── [presentation: max:6] │ ├── best: (scalar-group-by G2 G3 cols=()) - │ └── cost: 1074.54 + │ └── cost: 1085.04 ├── G2: (scan abc,cols=(2)) │ ├── [ordering: -2] [limit hint: 1.01] │ │ ├── best: (sort G2) - │ │ └── cost: 1293.84 + │ │ └── cost: 1304.34 │ └── [] │ ├── best: (scan abc,cols=(2)) - │ └── cost: 1064.51 + │ └── cost: 1075.01 ├── G3: (aggregations G6) ├── G4: (limit G7 G8 ordering=-2) │ └── [] │ ├── best: (limit G7="[ordering: -2] [limit hint: 1.00]" G8 ordering=-2) - │ └── cost: 1293.89 + │ └── cost: 1304.39 ├── G5: (aggregations G9) ├── G6: (max G10) ├── G7: (select G2 G11) │ ├── [ordering: -2] [limit hint: 1.00] │ │ ├── best: (select G2="[ordering: -2] [limit hint: 1.01]" G11) - │ │ └── cost: 1293.87 + │ │ └── cost: 1304.37 │ └── [] │ ├── best: (select G2 G11) - │ └── cost: 1074.53 + │ └── cost: 1085.03 ├── G8: (const 1) ├── G9: (const-agg G10) ├── G10: (variable b) @@ -690,28 +690,28 @@ memo (optimized, ~6KB, required=[presentation: max:6]) ├── G1: (scalar-group-by G2 G3 cols=()) (scalar-group-by G4 G5 cols=()) │ └── [presentation: max:6] │ ├── best: (scalar-group-by G2 G3 cols=()) - │ └── cost: 1074.54 + │ └── cost: 1085.04 ├── G2: (scan abc,cols=(2)) │ ├── [ordering: -2] [limit hint: 1.01] │ │ ├── best: (sort G2) - │ │ └── cost: 1293.84 + │ │ └── cost: 1304.34 │ └── [] │ ├── best: (scan abc,cols=(2)) - │ └── cost: 1064.51 + │ └── cost: 1075.01 ├── G3: (aggregations G6) ├── G4: (limit G7 G8 ordering=-2) │ └── [] │ ├── best: (limit G7="[ordering: -2] [limit hint: 1.00]" G8 ordering=-2) - │ └── cost: 1293.89 + │ └── cost: 1304.39 ├── G5: (aggregations G9) ├── G6: (max G10) ├── G7: (select G2 G11) │ ├── [ordering: -2] [limit hint: 1.00] │ │ ├── best: (select G2="[ordering: -2] [limit hint: 1.01]" G11) - │ │ └── cost: 1293.87 + │ │ └── cost: 1304.37 │ └── [] │ ├── best: (select G2 G11) - │ └── cost: 1074.53 + │ └── cost: 1085.03 ├── G8: (const 1) ├── G9: (const-agg G10) ├── G10: (variable b) @@ -1124,28 +1124,28 @@ memo (optimized, ~7KB, required=[presentation: array_agg:6]) ├── G1: (project G2 G3 array_agg) │ └── [presentation: array_agg:6] │ ├── best: (project G2 G3 array_agg) - │ └── cost: 1134.74 + │ └── cost: 1145.44 ├── G2: (group-by G4 G5 cols=(2,3),ordering=+4 opt(2,3)) (group-by G4 G5 cols=(2,3),ordering=+2,+3,+4) (group-by G4 G5 cols=(2,3),ordering=+4,+3,+2) (group-by G4 G5 cols=(2,3),ordering=+3,+4) │ └── [] │ ├── best: (group-by G4="[ordering: +2,+3,+4]" G5 cols=(2,3),ordering=+2,+3,+4) - │ └── cost: 1124.73 + │ └── cost: 1135.43 ├── G3: (projections) ├── G4: (scan kuvw,cols=(2-4)) (scan kuvw@uvw,cols=(2-4)) (scan kuvw@wvu,cols=(2-4)) (scan kuvw@vw,cols=(2-4)) (scan kuvw@w,cols=(2-4)) │ ├── [ordering: +2,+3,+4] │ │ ├── best: (scan kuvw@uvw,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ ├── [ordering: +3,+4] │ │ ├── best: (scan kuvw@vw,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ ├── [ordering: +4 opt(2,3)] │ │ ├── best: (scan kuvw@uvw,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ ├── [ordering: +4,+3,+2] │ │ ├── best: (scan kuvw@wvu,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan kuvw,cols=(2-4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G5: (aggregations G6) ├── G6: (array-agg G7) └── G7: (variable w) @@ -1158,25 +1158,25 @@ memo (optimized, ~6KB, required=[presentation: sum:6]) ├── G1: (project G2 G3 sum) │ └── [presentation: sum:6] │ ├── best: (project G2 G3 sum) - │ └── cost: 1144.74 + │ └── cost: 1155.44 ├── G2: (group-by G4 G5 cols=(2-4)) (group-by G4 G5 cols=(2-4),ordering=+2,+3,+4) (group-by G4 G5 cols=(2-4),ordering=+4,+3,+2) (group-by G4 G5 cols=(2-4),ordering=+3,+4) │ └── [] │ ├── best: (group-by G4="[ordering: +2,+3,+4]" G5 cols=(2-4),ordering=+2,+3,+4) - │ └── cost: 1134.73 + │ └── cost: 1145.43 ├── G3: (projections) ├── G4: (scan kuvw,cols=(2-4)) (scan kuvw@uvw,cols=(2-4)) (scan kuvw@wvu,cols=(2-4)) (scan kuvw@vw,cols=(2-4)) (scan kuvw@w,cols=(2-4)) │ ├── [ordering: +2,+3,+4] │ │ ├── best: (scan kuvw@uvw,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ ├── [ordering: +3,+4] │ │ ├── best: (scan kuvw@vw,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ ├── [ordering: +4,+3,+2] │ │ ├── best: (scan kuvw@wvu,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan kuvw,cols=(2-4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G5: (aggregations G6) ├── G6: (sum G7) └── G7: (variable w) @@ -1189,19 +1189,19 @@ memo (optimized, ~6KB, required=[presentation: sum:6]) ├── G1: (project G2 G3 sum) │ └── [presentation: sum:6] │ ├── best: (project G2 G3 sum) - │ └── cost: 1096.64 + │ └── cost: 1107.24 ├── G2: (group-by G4 G5 cols=(3)) (group-by G4 G5 cols=(3),ordering=+3) │ └── [] │ ├── best: (group-by G4="[ordering: +3]" G5 cols=(3),ordering=+3) - │ └── cost: 1095.63 + │ └── cost: 1106.23 ├── G3: (projections) ├── G4: (scan kuvw,cols=(3,4)) (scan kuvw@uvw,cols=(3,4)) (scan kuvw@wvu,cols=(3,4)) (scan kuvw@vw,cols=(3,4)) (scan kuvw@w,cols=(3,4)) │ ├── [ordering: +3] │ │ ├── best: (scan kuvw@vw,cols=(3,4)) - │ │ └── cost: 1074.61 + │ │ └── cost: 1085.21 │ └── [] │ ├── best: (scan kuvw,cols=(3,4)) - │ └── cost: 1074.61 + │ └── cost: 1085.21 ├── G5: (aggregations G6) ├── G6: (sum G7) └── G7: (variable w) @@ -1214,25 +1214,25 @@ memo (optimized, ~7KB, required=[presentation: array_agg:6]) ├── G1: (project G2 G3 array_agg) │ └── [presentation: array_agg:6] │ ├── best: (project G2 G3 array_agg) - │ └── cost: 1116.74 + │ └── cost: 1127.44 ├── G2: (group-by G4 G5 cols=(3),ordering=+2,+4 opt(3)) (group-by G4 G5 cols=(3),ordering=+2,+3,+4) │ └── [] │ ├── best: (group-by G4="[ordering: +2,+4 opt(3)]" G5 cols=(3),ordering=+2,+4 opt(3)) - │ └── cost: 1115.73 + │ └── cost: 1126.43 ├── G3: (projections) ├── G4: (scan kuvw,cols=(2-4)) (scan kuvw@uvw,cols=(2-4)) (scan kuvw@wvu,cols=(2-4)) (scan kuvw@vw,cols=(2-4)) (scan kuvw@w,cols=(2-4)) │ ├── [ordering: +2,+3,+4] │ │ ├── best: (scan kuvw@uvw,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ ├── [ordering: +2,+4 opt(3)] │ │ ├── best: (scan kuvw@uvw,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ ├── [ordering: +2] │ │ ├── best: (scan kuvw@uvw,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan kuvw,cols=(2-4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G5: (aggregations G6) ├── G6: (array-agg G7) └── G7: (variable w) @@ -1245,87 +1245,87 @@ memo (optimized, ~12KB, required=[presentation: array_agg:6]) ├── G1: (project G2 G3 array_agg) │ └── [presentation: array_agg:6] │ ├── best: (project G2 G3 array_agg) - │ └── cost: 1083.64 + │ └── cost: 1094.44 ├── G2: (group-by G4 G5 cols=(4),ordering=+(2|3) opt(4)) (group-by G4 G5 cols=(4),ordering=+(2|3)) (group-by G4 G5 cols=(4),ordering=+4,+(2|3)) (group-by G4 G5 cols=(4),ordering=+(2|3),+4) │ └── [] │ ├── best: (group-by G4="[ordering: +(2|3) opt(4)]" G5 cols=(4),ordering=+(2|3) opt(4)) - │ └── cost: 1083.54 + │ └── cost: 1094.34 ├── G3: (projections) ├── G4: (select G6 G7) (select G8 G7) (select G9 G7) │ ├── [ordering: +(2|3) opt(4)] │ │ ├── best: (select G8="[ordering: +2 opt(4)]" G7) - │ │ └── cost: 1083.13 + │ │ └── cost: 1093.93 │ ├── [ordering: +(2|3),+4] │ │ ├── best: (sort G4) - │ │ └── cost: 1084.42 + │ │ └── cost: 1095.22 │ ├── [ordering: +(2|3)] │ │ ├── best: (select G8="[ordering: +2]" G7) - │ │ └── cost: 1083.13 + │ │ └── cost: 1093.93 │ ├── [ordering: +4,+(2|3)] │ │ ├── best: (sort G4) - │ │ └── cost: 1084.42 + │ │ └── cost: 1095.22 │ └── [] │ ├── best: (select G8 G7) - │ └── cost: 1083.13 + │ └── cost: 1093.93 ├── G5: (aggregations G10) ├── G6: (scan kuvw,cols=(1-4)) (scan kuvw@uvw,cols=(1-4)) (scan kuvw@wvu,cols=(1-4)) (scan kuvw@vw,cols=(1-4)) (scan kuvw@w,cols=(1-4)) │ ├── [ordering: +2 opt(4)] │ │ ├── best: (scan kuvw@uvw,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ ├── [ordering: +2,+4] │ │ ├── best: (sort G6="[ordering: +2]") - │ │ └── cost: 1231.26 + │ │ └── cost: 1242.06 │ ├── [ordering: +2] │ │ ├── best: (scan kuvw@uvw,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ ├── [ordering: +4,+2] │ │ ├── best: (sort G6="[ordering: +4]") - │ │ └── cost: 1231.26 + │ │ └── cost: 1242.06 │ ├── [ordering: +4] │ │ ├── best: (scan kuvw@wvu,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ └── [] │ ├── best: (scan kuvw,cols=(1-4)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── G7: (filters G11) ├── G8: (scan kuvw@uvw,cols=(1-4),constrained) │ ├── [ordering: +2 opt(4)] │ │ ├── best: (scan kuvw@uvw,cols=(1-4),constrained) - │ │ └── cost: 1073.21 + │ │ └── cost: 1084.01 │ ├── [ordering: +2,+4] │ │ ├── best: (sort G8="[ordering: +2]") - │ │ └── cost: 1208.01 + │ │ └── cost: 1218.81 │ ├── [ordering: +2] │ │ ├── best: (scan kuvw@uvw,cols=(1-4),constrained) - │ │ └── cost: 1073.21 + │ │ └── cost: 1084.01 │ ├── [ordering: +4,+2] │ │ ├── best: (sort G8) - │ │ └── cost: 1340.50 + │ │ └── cost: 1351.30 │ ├── [ordering: +4] │ │ ├── best: (sort G8) - │ │ └── cost: 1329.66 + │ │ └── cost: 1340.46 │ └── [] │ ├── best: (scan kuvw@uvw,cols=(1-4),constrained) - │ └── cost: 1073.21 + │ └── cost: 1084.01 ├── G9: (scan kuvw@vw,cols=(1-4),constrained) │ ├── [ordering: +2 opt(4)] │ │ ├── best: (sort G9) - │ │ └── cost: 1329.66 + │ │ └── cost: 1340.46 │ ├── [ordering: +2,+4] │ │ ├── best: (sort G9) - │ │ └── cost: 1340.50 + │ │ └── cost: 1351.30 │ ├── [ordering: +2] │ │ ├── best: (sort G9) - │ │ └── cost: 1329.66 + │ │ └── cost: 1340.46 │ ├── [ordering: +4,+2] │ │ ├── best: (sort G9) - │ │ └── cost: 1340.50 + │ │ └── cost: 1351.30 │ ├── [ordering: +4] │ │ ├── best: (sort G9) - │ │ └── cost: 1329.66 + │ │ └── cost: 1340.46 │ └── [] │ ├── best: (scan kuvw@vw,cols=(1-4),constrained) - │ └── cost: 1073.21 + │ └── cost: 1084.01 ├── G10: (array-agg G12) ├── G11: (eq G13 G14) ├── G12: (variable k) @@ -1339,54 +1339,54 @@ memo (optimized, ~12KB, required=[presentation: sum:6]) ├── G1: (project G2 G3 sum) │ └── [presentation: sum:6] │ ├── best: (project G2 G3 sum) - │ └── cost: 1083.70 + │ └── cost: 1094.50 ├── G2: (group-by G4 G5 cols=(2,4)) (group-by G4 G5 cols=(2,4),ordering=+(2|3)) (group-by G4 G5 cols=(2,4),ordering=+4) │ └── [] │ ├── best: (group-by G4="[ordering: +(2|3)]" G5 cols=(2,4),ordering=+(2|3)) - │ └── cost: 1083.59 + │ └── cost: 1094.39 ├── G3: (projections) ├── G4: (select G6 G7) (select G8 G7) (select G9 G7) │ ├── [ordering: +(2|3)] │ │ ├── best: (select G8="[ordering: +2]" G7) - │ │ └── cost: 1083.13 + │ │ └── cost: 1093.93 │ ├── [ordering: +4] │ │ ├── best: (sort G4) - │ │ └── cost: 1084.37 + │ │ └── cost: 1095.17 │ └── [] │ ├── best: (select G8 G7) - │ └── cost: 1083.13 + │ └── cost: 1093.93 ├── G5: (aggregations G10) ├── G6: (scan kuvw,cols=(1-4)) (scan kuvw@uvw,cols=(1-4)) (scan kuvw@wvu,cols=(1-4)) (scan kuvw@vw,cols=(1-4)) (scan kuvw@w,cols=(1-4)) │ ├── [ordering: +2] │ │ ├── best: (scan kuvw@uvw,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ ├── [ordering: +4] │ │ ├── best: (scan kuvw@wvu,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ └── [] │ ├── best: (scan kuvw,cols=(1-4)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── G7: (filters G11) ├── G8: (scan kuvw@uvw,cols=(1-4),constrained) │ ├── [ordering: +2] │ │ ├── best: (scan kuvw@uvw,cols=(1-4),constrained) - │ │ └── cost: 1073.21 + │ │ └── cost: 1084.01 │ ├── [ordering: +4] │ │ ├── best: (sort G8) - │ │ └── cost: 1329.66 + │ │ └── cost: 1340.46 │ └── [] │ ├── best: (scan kuvw@uvw,cols=(1-4),constrained) - │ └── cost: 1073.21 + │ └── cost: 1084.01 ├── G9: (scan kuvw@vw,cols=(1-4),constrained) │ ├── [ordering: +2] │ │ ├── best: (sort G9) - │ │ └── cost: 1329.66 + │ │ └── cost: 1340.46 │ ├── [ordering: +4] │ │ ├── best: (sort G9) - │ │ └── cost: 1329.66 + │ │ └── cost: 1340.46 │ └── [] │ ├── best: (scan kuvw@vw,cols=(1-4),constrained) - │ └── cost: 1073.21 + │ └── cost: 1084.01 ├── G10: (sum G12) ├── G11: (eq G13 G14) ├── G12: (variable k) @@ -1401,19 +1401,19 @@ memo (optimized, ~6KB, required=[presentation: array_agg:6]) ├── G1: (project G2 G3 array_agg) │ └── [presentation: array_agg:6] │ ├── best: (project G2 G3 array_agg) - │ └── cost: 1245.54 + │ └── cost: 1257.09 ├── G2: (group-by G4 G5 cols=(2,3),ordering=-4 opt(2,3)) │ └── [] │ ├── best: (group-by G4="[ordering: -4 opt(2,3)]" G5 cols=(2,3),ordering=-4 opt(2,3)) - │ └── cost: 1235.53 + │ └── cost: 1247.08 ├── G3: (projections) ├── G4: (scan kuvw,cols=(2-4)) (scan kuvw@uvw,cols=(2-4)) (scan kuvw@wvu,cols=(2-4)) (scan kuvw@vw,cols=(2-4)) (scan kuvw@w,cols=(2-4)) │ ├── [ordering: -4 opt(2,3)] │ │ ├── best: (scan kuvw@uvw,rev,cols=(2-4)) - │ │ └── cost: 1185.51 + │ │ └── cost: 1197.06 │ └── [] │ ├── best: (scan kuvw,cols=(2-4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G5: (aggregations G6) ├── G6: (array-agg G7) └── G7: (variable w) @@ -1427,20 +1427,20 @@ memo (optimized, ~5KB, required=[presentation: u:2,v:3,w:4]) ├── G1: (distinct-on G2 G3 cols=(2-4)) (distinct-on G2 G3 cols=(2-4),ordering=+2,+3,+4) (distinct-on G2 G3 cols=(2-4),ordering=+4,+3,+2) (distinct-on G2 G3 cols=(2-4),ordering=+3,+4) │ └── [presentation: u:2,v:3,w:4] │ ├── best: (distinct-on G2="[ordering: +2,+3,+4]" G3 cols=(2-4),ordering=+2,+3,+4) - │ └── cost: 1124.73 + │ └── cost: 1135.43 ├── G2: (scan kuvw,cols=(2-4)) (scan kuvw@uvw,cols=(2-4)) (scan kuvw@wvu,cols=(2-4)) (scan kuvw@vw,cols=(2-4)) (scan kuvw@w,cols=(2-4)) │ ├── [ordering: +2,+3,+4] │ │ ├── best: (scan kuvw@uvw,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ ├── [ordering: +3,+4] │ │ ├── best: (scan kuvw@vw,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ ├── [ordering: +4,+3,+2] │ │ ├── best: (scan kuvw@wvu,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan kuvw,cols=(2-4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 └── G3: (aggregations) # Orderings +u,+v and +v can be used. @@ -1451,17 +1451,17 @@ memo (optimized, ~5KB, required=[presentation: u:2,v:3,w:4]) ├── G1: (distinct-on G2 G3 cols=(2,3)) (distinct-on G2 G3 cols=(2,3),ordering=+2,+3) (distinct-on G2 G3 cols=(2,3),ordering=+3) │ └── [presentation: u:2,v:3,w:4] │ ├── best: (distinct-on G2="[ordering: +2,+3]" G3 cols=(2,3),ordering=+2,+3) - │ └── cost: 1124.73 + │ └── cost: 1135.43 ├── G2: (scan kuvw,cols=(2-4)) (scan kuvw@uvw,cols=(2-4)) (scan kuvw@wvu,cols=(2-4)) (scan kuvw@vw,cols=(2-4)) (scan kuvw@w,cols=(2-4)) │ ├── [ordering: +2,+3] │ │ ├── best: (scan kuvw@uvw,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ ├── [ordering: +3] │ │ ├── best: (scan kuvw@vw,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan kuvw,cols=(2-4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G3: (aggregations G4) ├── G4: (first-agg G5) └── G5: (variable w) @@ -1474,14 +1474,14 @@ memo (optimized, ~4KB, required=[presentation: u:2,v:3,w:4]) ├── G1: (distinct-on G2 G3 cols=(2)) (distinct-on G2 G3 cols=(2),ordering=+2) │ └── [presentation: u:2,v:3,w:4] │ ├── best: (distinct-on G2="[ordering: +2]" G3 cols=(2),ordering=+2) - │ └── cost: 1115.73 + │ └── cost: 1126.43 ├── G2: (scan kuvw,cols=(2-4)) (scan kuvw@uvw,cols=(2-4)) (scan kuvw@wvu,cols=(2-4)) (scan kuvw@vw,cols=(2-4)) (scan kuvw@w,cols=(2-4)) │ ├── [ordering: +2] │ │ ├── best: (scan kuvw@uvw,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan kuvw,cols=(2-4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G3: (aggregations G4 G5) ├── G4: (first-agg G6) ├── G5: (first-agg G7) @@ -1496,14 +1496,14 @@ memo (optimized, ~4KB, required=[presentation: u:2,v:3,w:4]) ├── G1: (distinct-on G2 G3 cols=(3)) (distinct-on G2 G3 cols=(3),ordering=+3) │ └── [presentation: u:2,v:3,w:4] │ ├── best: (distinct-on G2="[ordering: +3]" G3 cols=(3),ordering=+3) - │ └── cost: 1115.73 + │ └── cost: 1126.43 ├── G2: (scan kuvw,cols=(2-4)) (scan kuvw@uvw,cols=(2-4)) (scan kuvw@wvu,cols=(2-4)) (scan kuvw@vw,cols=(2-4)) (scan kuvw@w,cols=(2-4)) │ ├── [ordering: +3] │ │ ├── best: (scan kuvw@vw,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan kuvw,cols=(2-4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G3: (aggregations G4 G5) ├── G4: (first-agg G6) ├── G5: (first-agg G7) @@ -1518,14 +1518,14 @@ memo (optimized, ~4KB, required=[presentation: u:2,v:3,w:4]) ├── G1: (distinct-on G2 G3 cols=(4)) (distinct-on G2 G3 cols=(4),ordering=+4) │ └── [presentation: u:2,v:3,w:4] │ ├── best: (distinct-on G2="[ordering: +4]" G3 cols=(4),ordering=+4) - │ └── cost: 1115.73 + │ └── cost: 1126.43 ├── G2: (scan kuvw,cols=(2-4)) (scan kuvw@uvw,cols=(2-4)) (scan kuvw@wvu,cols=(2-4)) (scan kuvw@vw,cols=(2-4)) (scan kuvw@w,cols=(2-4)) │ ├── [ordering: +4] │ │ ├── best: (scan kuvw@wvu,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan kuvw,cols=(2-4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G3: (aggregations G4 G5) ├── G4: (first-agg G6) ├── G5: (first-agg G7) @@ -1540,26 +1540,26 @@ memo (optimized, ~4KB, required=[presentation: u:2,v:3,w:4] [ordering: +2]) ├── G1: (distinct-on G2 G3 cols=(2),ordering=+4 opt(2)) (distinct-on G2 G3 cols=(2),ordering=+4) │ ├── [presentation: u:2,v:3,w:4] [ordering: +2] │ │ ├── best: (sort G1) - │ │ └── cost: 1144.03 + │ │ └── cost: 1154.73 │ └── [] │ ├── best: (distinct-on G2="[ordering: +4 opt(2)]" G3 cols=(2),ordering=+4 opt(2)) - │ └── cost: 1125.73 + │ └── cost: 1136.43 ├── G2: (scan kuvw,cols=(2-4)) (scan kuvw@uvw,cols=(2-4)) (scan kuvw@wvu,cols=(2-4)) (scan kuvw@vw,cols=(2-4)) (scan kuvw@w,cols=(2-4)) │ ├── [ordering: +2,+4] │ │ ├── best: (sort G2="[ordering: +2]") - │ │ └── cost: 1211.16 + │ │ └── cost: 1221.86 │ ├── [ordering: +2] │ │ ├── best: (scan kuvw@uvw,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ ├── [ordering: +4 opt(2)] │ │ ├── best: (scan kuvw@wvu,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ ├── [ordering: +4] │ │ ├── best: (scan kuvw@wvu,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan kuvw,cols=(2-4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G3: (aggregations G4 G5) ├── G4: (first-agg G6) ├── G5: (first-agg G7) @@ -1574,23 +1574,23 @@ memo (optimized, ~5KB, required=[presentation: u:2,v:3,w:4] [ordering: +2]) ├── G1: (distinct-on G2 G3 cols=(2),ordering=+3,+4 opt(2)) (distinct-on G2 G3 cols=(2),ordering=+2,+3,+4) (distinct-on G2 G3 cols=(2),ordering=+3,+4) │ ├── [presentation: u:2,v:3,w:4] [ordering: +2] │ │ ├── best: (distinct-on G2="[ordering: +2,+3,+4]" G3 cols=(2),ordering=+3,+4 opt(2)) - │ │ └── cost: 1115.73 + │ │ └── cost: 1126.43 │ └── [] │ ├── best: (distinct-on G2="[ordering: +2,+3,+4]" G3 cols=(2),ordering=+2,+3,+4) - │ └── cost: 1115.73 + │ └── cost: 1126.43 ├── G2: (scan kuvw,cols=(2-4)) (scan kuvw@uvw,cols=(2-4)) (scan kuvw@wvu,cols=(2-4)) (scan kuvw@vw,cols=(2-4)) (scan kuvw@w,cols=(2-4)) │ ├── [ordering: +2,+3,+4] │ │ ├── best: (scan kuvw@uvw,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ ├── [ordering: +3,+4 opt(2)] │ │ ├── best: (scan kuvw@uvw,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ ├── [ordering: +3,+4] │ │ ├── best: (scan kuvw@vw,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan kuvw,cols=(2-4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G3: (aggregations G4 G5) ├── G4: (first-agg G6) ├── G5: (first-agg G7) @@ -1605,23 +1605,23 @@ memo (optimized, ~4KB, required=[presentation: u:2,v:3,w:4] [ordering: +4,+2]) ├── G1: (distinct-on G2 G3 cols=(2,4),ordering=-3 opt(2,4)) │ ├── [presentation: u:2,v:3,w:4] [ordering: +4,+2] │ │ ├── best: (distinct-on G2="[ordering: +4,+2,-3]" G3 cols=(2,4),ordering=-3 opt(2,4)) - │ │ └── cost: 1255.50 + │ │ └── cost: 1266.20 │ └── [] │ ├── best: (distinct-on G2="[ordering: -3 opt(2,4)]" G3 cols=(2,4),ordering=-3 opt(2,4)) - │ └── cost: 1235.53 + │ └── cost: 1247.08 ├── G2: (scan kuvw,cols=(2-4)) (scan kuvw@uvw,cols=(2-4)) (scan kuvw@wvu,cols=(2-4)) (scan kuvw@vw,cols=(2-4)) (scan kuvw@w,cols=(2-4)) │ ├── [ordering: +4,+2,-3] │ │ ├── best: (sort G2="[ordering: +4]") - │ │ └── cost: 1215.48 + │ │ └── cost: 1226.18 │ ├── [ordering: +4] │ │ ├── best: (scan kuvw@wvu,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ ├── [ordering: -3 opt(2,4)] │ │ ├── best: (scan kuvw@uvw,rev,cols=(2-4)) - │ │ └── cost: 1185.51 + │ │ └── cost: 1197.06 │ └── [] │ ├── best: (scan kuvw,cols=(2-4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G3: (aggregations G4) ├── G4: (first-agg G5) └── G5: (variable v) @@ -1633,23 +1633,23 @@ memo (optimized, ~4KB, required=[presentation: u:2,v:3,w:4] [ordering: +4]) ├── G1: (distinct-on G2 G3 cols=(4),ordering=-2,+3 opt(4)) │ ├── [presentation: u:2,v:3,w:4] [ordering: +4] │ │ ├── best: (distinct-on G2="[ordering: +4,-2,+3]" G3 cols=(4),ordering=-2,+3 opt(4)) - │ │ └── cost: 1246.50 + │ │ └── cost: 1257.20 │ └── [] │ ├── best: (distinct-on G2="[ordering: -2,+3 opt(4)]" G3 cols=(4),ordering=-2,+3 opt(4)) - │ └── cost: 1386.02 + │ └── cost: 1396.72 ├── G2: (scan kuvw,cols=(2-4)) (scan kuvw@uvw,cols=(2-4)) (scan kuvw@wvu,cols=(2-4)) (scan kuvw@vw,cols=(2-4)) (scan kuvw@w,cols=(2-4)) │ ├── [ordering: +4,-2,+3] │ │ ├── best: (sort G2="[ordering: +4]") - │ │ └── cost: 1215.48 + │ │ └── cost: 1226.18 │ ├── [ordering: +4] │ │ ├── best: (scan kuvw@wvu,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ ├── [ordering: -2,+3 opt(4)] │ │ ├── best: (sort G2) - │ │ └── cost: 1345.00 + │ │ └── cost: 1355.70 │ └── [] │ ├── best: (scan kuvw,cols=(2-4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G3: (aggregations G4 G5) ├── G4: (first-agg G6) ├── G5: (first-agg G7) @@ -1663,20 +1663,20 @@ memo (optimized, ~4KB, required=[presentation: u:2,v:3,w:4] [ordering: -4]) ├── G1: (distinct-on G2 G3 cols=(4),ordering=-2,+3 opt(4)) │ ├── [presentation: u:2,v:3,w:4] [ordering: -4] │ │ ├── best: (distinct-on G2="[ordering: -4,-2,+3]" G3 cols=(4),ordering=-2,+3 opt(4)) - │ │ └── cost: 1377.12 + │ │ └── cost: 1387.82 │ └── [] │ ├── best: (distinct-on G2="[ordering: -2,+3 opt(4)]" G3 cols=(4),ordering=-2,+3 opt(4)) - │ └── cost: 1386.02 + │ └── cost: 1396.72 ├── G2: (scan kuvw,cols=(2-4)) (scan kuvw@uvw,cols=(2-4)) (scan kuvw@wvu,cols=(2-4)) (scan kuvw@vw,cols=(2-4)) (scan kuvw@w,cols=(2-4)) │ ├── [ordering: -2,+3 opt(4)] │ │ ├── best: (sort G2) - │ │ └── cost: 1345.00 + │ │ └── cost: 1355.70 │ ├── [ordering: -4,-2,+3] │ │ ├── best: (sort G2) - │ │ └── cost: 1346.10 + │ │ └── cost: 1356.80 │ └── [] │ ├── best: (scan kuvw,cols=(2-4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G3: (aggregations G4 G5) ├── G4: (first-agg G6) ├── G5: (first-agg G7) @@ -1690,26 +1690,26 @@ memo (optimized, ~4KB, required=[presentation: u:2,v:3,w:4] [ordering: +4]) ├── G1: (distinct-on G2 G3 cols=(4),ordering=+2,-3 opt(4)) │ ├── [presentation: u:2,v:3,w:4] [ordering: +4] │ │ ├── best: (distinct-on G2="[ordering: +4,+2,-3]" G3 cols=(4),ordering=+2,-3 opt(4)) - │ │ └── cost: 1246.50 + │ │ └── cost: 1257.20 │ └── [] │ ├── best: (distinct-on G2="[ordering: +2,-3 opt(4)]" G3 cols=(4),ordering=+2,-3 opt(4)) - │ └── cost: 1252.18 + │ └── cost: 1262.88 ├── G2: (scan kuvw,cols=(2-4)) (scan kuvw@uvw,cols=(2-4)) (scan kuvw@wvu,cols=(2-4)) (scan kuvw@vw,cols=(2-4)) (scan kuvw@w,cols=(2-4)) │ ├── [ordering: +2,-3 opt(4)] │ │ ├── best: (sort G2="[ordering: +2]") - │ │ └── cost: 1211.16 + │ │ └── cost: 1221.86 │ ├── [ordering: +2] │ │ ├── best: (scan kuvw@uvw,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ ├── [ordering: +4,+2,-3] │ │ ├── best: (sort G2="[ordering: +4]") - │ │ └── cost: 1215.48 + │ │ └── cost: 1226.18 │ ├── [ordering: +4] │ │ ├── best: (scan kuvw@wvu,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan kuvw,cols=(2-4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G3: (aggregations G4 G5) ├── G4: (first-agg G6) ├── G5: (first-agg G7) @@ -1724,79 +1724,79 @@ memo (optimized, ~37KB, required=[presentation: w:10] [ordering: +11,+1]) ├── G1: (project G2 G3 x) │ ├── [presentation: w:10] [ordering: +11,+1] │ │ ├── best: (sort G1) - │ │ └── cost: 1400.63 + │ │ └── cost: 1421.63 │ └── [] │ ├── best: (project G2 G3 x) - │ └── cost: 1140.33 + │ └── cost: 1161.33 ├── G2: (ensure-distinct-on G4 G5 cols=(1)) (ensure-distinct-on G4 G5 cols=(1),ordering=+1) │ └── [] │ ├── best: (ensure-distinct-on G4="[ordering: +1]" G5 cols=(1),ordering=+1) - │ └── cost: 1110.32 + │ └── cost: 1131.32 ├── G3: (projections G6 G7) ├── G4: (left-join G8 G9 G10) (left-join G8 G9 G10) (right-join G9 G8 G10) (merge-join G8 G9 G11 left-join,+1,+6) (lookup-join G12 G11 kuvw@uvw,keyCols=[1 12],outCols=(1,6-8)) (lookup-join G13 G10 kuvw@vw,keyCols=[13],outCols=(1,6-8)) (right-join G9 G8 G10) (merge-join G8 G9 G11 left-join,+1,+6) (lookup-join G14 G11 kuvw@uvw,keyCols=[1 14],outCols=(1,6-8)) (lookup-join G15 G10 kuvw@vw,keyCols=[15],outCols=(1,6-8)) (merge-join G9 G8 G11 right-join,+6,+1) (merge-join G9 G8 G11 right-join,+6,+1) │ ├── [ordering: +1] │ │ ├── best: (merge-join G8="[ordering: +1]" G9="[ordering: +6 opt(7)]" G11 left-join,+1,+6) - │ │ └── cost: 1080.30 + │ │ └── cost: 1101.30 │ └── [] │ ├── best: (merge-join G8="[ordering: +1]" G9="[ordering: +6 opt(7)]" G11 left-join,+1,+6) - │ └── cost: 1080.30 + │ └── cost: 1101.30 ├── G5: (aggregations G16) ├── G6: (variable kuvw.w) ├── G7: (plus G17 G18) ├── G8: (scan xyz,cols=(1)) (scan xyz@xy,cols=(1)) (scan xyz@zyx,cols=(1)) (scan xyz@yy,cols=(1)) │ ├── [ordering: +1] │ │ ├── best: (scan xyz@xy,cols=(1)) - │ │ └── cost: 1044.31 + │ │ └── cost: 1054.61 │ └── [] │ ├── best: (scan xyz@xy,cols=(1)) - │ └── cost: 1044.31 + │ └── cost: 1054.61 ├── G9: (select G19 G20) (scan kuvw@vw,cols=(6-8),constrained) │ ├── [ordering: +6 opt(7)] │ │ ├── best: (sort G9) - │ │ └── cost: 15.88 + │ │ └── cost: 26.58 │ └── [] │ ├── best: (scan kuvw@vw,cols=(6-8),constrained) - │ └── cost: 14.71 + │ └── cost: 25.41 ├── G10: (filters G21) ├── G11: (filters) ├── G12: (project G8 G22 x) │ ├── [ordering: +1] │ │ ├── best: (project G8="[ordering: +1]" G22 x) - │ │ └── cost: 1064.32 + │ │ └── cost: 1074.62 │ └── [] │ ├── best: (project G8 G22 x) - │ └── cost: 1064.32 + │ └── cost: 1074.62 ├── G13: (project G8 G22 x) │ ├── [ordering: +1] │ │ ├── best: (project G8="[ordering: +1]" G22 x) - │ │ └── cost: 1064.32 + │ │ └── cost: 1074.62 │ └── [] │ ├── best: (project G8 G22 x) - │ └── cost: 1064.32 + │ └── cost: 1074.62 ├── G14: (project G8 G22 x) │ ├── [ordering: +1] │ │ ├── best: (project G8="[ordering: +1]" G22 x) - │ │ └── cost: 1064.32 + │ │ └── cost: 1074.62 │ └── [] │ ├── best: (project G8 G22 x) - │ └── cost: 1064.32 + │ └── cost: 1074.62 ├── G15: (project G8 G22 x) │ ├── [ordering: +1] │ │ ├── best: (project G8="[ordering: +1]" G22 x) - │ │ └── cost: 1064.32 + │ │ └── cost: 1074.62 │ └── [] │ ├── best: (project G8 G22 x) - │ └── cost: 1064.32 + │ └── cost: 1074.62 ├── G16: (const-agg G6) ├── G17: (variable x) ├── G18: (const 1) ├── G19: (scan kuvw,cols=(6-8)) (scan kuvw@uvw,cols=(6-8)) (scan kuvw@wvu,cols=(6-8)) (scan kuvw@vw,cols=(6-8)) (scan kuvw@w,cols=(6-8)) │ ├── [ordering: +6 opt(7)] │ │ ├── best: (scan kuvw@uvw,cols=(6-8)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan kuvw,cols=(6-8)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G20: (filters G23) ├── G21: (eq G17 G24) ├── G22: (projections G18) @@ -1812,35 +1812,35 @@ memo (optimized, ~30KB, required=[]) ├── G1: (insert G2 G3 G4 xyz) │ └── [] │ ├── best: (insert G2 G3 G4 xyz) - │ └── cost: 2168.87 + │ └── cost: 2189.77 ├── G2: (upsert-distinct-on G5 G6 cols=(7)) (upsert-distinct-on G5 G6 cols=(7),ordering=+7 opt(10)) │ └── [] │ ├── best: (upsert-distinct-on G5 G6 cols=(7)) - │ └── cost: 2168.86 + │ └── cost: 2189.76 ├── G3: (unique-checks) ├── G4: (f-k-checks) ├── G5: (anti-join G7 G8 G9) (anti-join G7 G8 G9) (merge-join G7 G8 G10 anti-join,+7,+11) (lookup-join G7 G10 xyz,keyCols=[7],outCols=(7,8,10,11)) (lookup-join G7 G10 xyz@xy,keyCols=[7],outCols=(7,8,10,11)) (merge-join G7 G8 G10 anti-join,+7,+11) (lookup-join G7 G10 xyz,keyCols=[7],outCols=(7,8,10,11)) (lookup-join G7 G10 xyz@xy,keyCols=[7],outCols=(7,8,10,11)) │ ├── [ordering: +7 opt(10)] │ │ ├── best: (merge-join G7="[ordering: +7 opt(10)]" G8="[ordering: +11]" G10 anti-join,+7,+11) - │ │ └── cost: 2168.84 + │ │ └── cost: 2189.74 │ └── [] │ ├── best: (merge-join G7="[ordering: +7 opt(10)]" G8="[ordering: +11]" G10 anti-join,+7,+11) - │ └── cost: 2168.84 + │ └── cost: 2189.74 ├── G6: (aggregations G11 G12) ├── G7: (project G13 G14 v w) │ ├── [ordering: +7 opt(10)] │ │ ├── best: (project G13="[ordering: +7]" G14 v w) - │ │ └── cost: 1094.62 + │ │ └── cost: 1105.22 │ └── [] │ ├── best: (project G13 G14 v w) - │ └── cost: 1094.62 + │ └── cost: 1105.22 ├── G8: (scan xyz,cols=(11)) (scan xyz@xy,cols=(11)) (scan xyz@zyx,cols=(11)) (scan xyz@yy,cols=(11)) │ ├── [ordering: +11] │ │ ├── best: (scan xyz@xy,cols=(11)) - │ │ └── cost: 1044.31 + │ │ └── cost: 1054.61 │ └── [] │ ├── best: (scan xyz@xy,cols=(11)) - │ └── cost: 1044.31 + │ └── cost: 1054.61 ├── G9: (filters G15) ├── G10: (filters) ├── G11: (first-agg G16) @@ -1848,10 +1848,10 @@ memo (optimized, ~30KB, required=[]) ├── G13: (scan kuvw,cols=(7,8)) (scan kuvw@uvw,cols=(7,8)) (scan kuvw@wvu,cols=(7,8)) (scan kuvw@vw,cols=(7,8)) (scan kuvw@w,cols=(7,8)) │ ├── [ordering: +7] │ │ ├── best: (scan kuvw@vw,cols=(7,8)) - │ │ └── cost: 1074.61 + │ │ └── cost: 1085.21 │ └── [] │ ├── best: (scan kuvw,cols=(7,8)) - │ └── cost: 1074.61 + │ └── cost: 1085.21 ├── G14: (projections G18) ├── G15: (eq G19 G20) ├── G16: (variable w) @@ -1868,50 +1868,50 @@ memo (optimized, ~27KB, required=[]) ├── G1: (upsert G2 G3 G4 xyz) │ └── [] │ ├── best: (upsert G2 G3 G4 xyz) - │ └── cost: 2259.28 + │ └── cost: 2280.48 ├── G2: (project G5 G6 v w ?column? x y z) │ └── [] │ ├── best: (project G5 G6 v w ?column? x y z) - │ └── cost: 2259.27 + │ └── cost: 2280.47 ├── G3: (unique-checks) ├── G4: (f-k-checks) ├── G5: (left-join G7 G8 G9) (left-join G7 G8 G9) (right-join G8 G7 G9) (lookup-join G7 G10 xyz,keyCols=[7],outCols=(7,8,10-13)) (lookup-join G11 G10 xyz,keyCols=[11],outCols=(7,8,10-13)) (right-join G8 G7 G9) (lookup-join G7 G10 xyz,keyCols=[7],outCols=(7,8,10-13)) (lookup-join G12 G10 xyz,keyCols=[11],outCols=(7,8,10-13)) (merge-join G8 G7 G10 right-join,+11,+7) (merge-join G8 G7 G10 right-join,+11,+7) │ └── [] │ ├── best: (merge-join G8="[ordering: +11]" G7="[ordering: +7 opt(10)]" G10 right-join,+11,+7) - │ └── cost: 2239.26 + │ └── cost: 2260.46 ├── G6: (projections G13) ├── G7: (ensure-upsert-distinct-on G14 G15 cols=(7)) (ensure-upsert-distinct-on G14 G15 cols=(7),ordering=+7 opt(10)) │ ├── [ordering: +7 opt(10)] │ │ ├── best: (ensure-upsert-distinct-on G14="[ordering: +7 opt(10)]" G15 cols=(7)) - │ │ └── cost: 1134.64 + │ │ └── cost: 1145.24 │ └── [] │ ├── best: (ensure-upsert-distinct-on G14="[ordering: +7 opt(10)]" G15 cols=(7),ordering=+7 opt(10)) - │ └── cost: 1134.64 + │ └── cost: 1145.24 ├── G8: (scan xyz,cols=(11-13)) (scan xyz@zyx,cols=(11-13)) │ ├── [ordering: +11] │ │ ├── best: (scan xyz,cols=(11-13)) - │ │ └── cost: 1074.61 + │ │ └── cost: 1085.21 │ └── [] │ ├── best: (scan xyz,cols=(11-13)) - │ └── cost: 1074.61 + │ └── cost: 1085.21 ├── G9: (filters G16) ├── G10: (filters) ├── G11: (lookup-join G7 G10 xyz@xy,keyCols=[7],outCols=(7,8,10-12)) │ └── [] │ ├── best: (lookup-join G7 G10 xyz@xy,keyCols=[7],outCols=(7,8,10-12)) - │ └── cost: 7184.65 + │ └── cost: 7195.25 ├── G12: (lookup-join G7 G10 xyz@xy,keyCols=[7],outCols=(7,8,10-12)) │ └── [] │ ├── best: (lookup-join G7 G10 xyz@xy,keyCols=[7],outCols=(7,8,10-12)) - │ └── cost: 7184.65 + │ └── cost: 7195.25 ├── G13: (case G17 G18 G19) ├── G14: (project G20 G21 v w) │ ├── [ordering: +7 opt(10)] │ │ ├── best: (project G20="[ordering: +7]" G21 v w) - │ │ └── cost: 1094.62 + │ │ └── cost: 1105.22 │ └── [] │ ├── best: (project G20 G21 v w) - │ └── cost: 1094.62 + │ └── cost: 1105.22 ├── G15: (aggregations G22 G23) ├── G16: (eq G24 G25) ├── G17: (true) @@ -1920,10 +1920,10 @@ memo (optimized, ~27KB, required=[]) ├── G20: (scan kuvw,cols=(7,8)) (scan kuvw@uvw,cols=(7,8)) (scan kuvw@wvu,cols=(7,8)) (scan kuvw@vw,cols=(7,8)) (scan kuvw@w,cols=(7,8)) │ ├── [ordering: +7] │ │ ├── best: (scan kuvw@vw,cols=(7,8)) - │ │ └── cost: 1074.61 + │ │ └── cost: 1085.21 │ └── [] │ ├── best: (scan kuvw,cols=(7,8)) - │ └── cost: 1074.61 + │ └── cost: 1085.21 ├── G21: (projections G27) ├── G22: (first-agg G28) ├── G23: (first-agg G29) diff --git a/pkg/sql/opt/xform/testdata/rules/join b/pkg/sql/opt/xform/testdata/rules/join index 41e44e97fa95..5018f8f8c98b 100644 --- a/pkg/sql/opt/xform/testdata/rules/join +++ b/pkg/sql/opt/xform/testdata/rules/join @@ -174,51 +174,51 @@ memo (optimized, ~38KB, required=[presentation: a:1,b:2,c:3,s:6,t:7,u:8,x:10,y:1 ├── G1: (inner-join G2 G3 G4) (inner-join G2 G3 G4) (inner-join G3 G2 G4) (inner-join G5 G6 G7) (inner-join G6 G5 G7) (inner-join G8 G9 G7) (inner-join G9 G8 G7) (merge-join G2 G3 G10 inner-join,+1,+6) (merge-join G2 G3 G10 inner-join,+1,+6) (merge-join G3 G2 G10 inner-join,+6,+1) (lookup-join G3 G10 abc@ab,keyCols=[6],outCols=(1-3,6-8,10-12)) (merge-join G5 G6 G10 inner-join,+6,+10) (merge-join G6 G5 G10 inner-join,+10,+6) (lookup-join G6 G10 stu,keyCols=[10],outCols=(1-3,6-8,10-12)) (merge-join G8 G9 G10 inner-join,+6,+10) (lookup-join G8 G10 xyz@xy,keyCols=[6],outCols=(1-3,6-8,10-12)) (merge-join G9 G8 G10 inner-join,+10,+6) │ └── [presentation: a:1,b:2,c:3,s:6,t:7,u:8,x:10,y:11,z:12] │ ├── best: (merge-join G5="[ordering: +6]" G6="[ordering: +(1|10)]" G10 inner-join,+6,+10) - │ └── cost: 13024.05 + │ └── cost: 13056.05 ├── G2: (scan abc,cols=(1-3)) (scan abc@ab,cols=(1-3)) (scan abc@bc,cols=(1-3)) │ ├── [ordering: +1] │ │ ├── best: (scan abc@ab,cols=(1-3)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan abc,cols=(1-3)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G3: (inner-join G5 G9 G7) (inner-join G5 G9 G7) (inner-join G9 G5 G7) (merge-join G5 G9 G10 inner-join,+6,+10) (lookup-join G5 G10 xyz@xy,keyCols=[6],outCols=(6-8,10-12)) (merge-join G5 G9 G10 inner-join,+6,+10) (lookup-join G5 G10 xyz@xy,keyCols=[6],outCols=(6-8,10-12)) (merge-join G9 G5 G10 inner-join,+10,+6) (lookup-join G9 G10 stu,keyCols=[10],outCols=(6-8,10-12)) │ ├── [ordering: +(6|10)] │ │ ├── best: (merge-join G5="[ordering: +6]" G9="[ordering: +10]" G10 inner-join,+6,+10) - │ │ └── cost: 11909.33 + │ │ └── cost: 11930.63 │ └── [] │ ├── best: (merge-join G5="[ordering: +6]" G9="[ordering: +10]" G10 inner-join,+6,+10) - │ └── cost: 11909.33 + │ └── cost: 11930.63 ├── G4: (filters G11) ├── G5: (scan stu,cols=(6-8)) (scan stu@uts,cols=(6-8)) │ ├── [ordering: +6] │ │ ├── best: (scan stu,cols=(6-8)) - │ │ └── cost: 10614.61 + │ │ └── cost: 10625.21 │ └── [] │ ├── best: (scan stu,cols=(6-8)) - │ └── cost: 10614.61 + │ └── cost: 10625.21 ├── G6: (inner-join G2 G9 G12) (inner-join G9 G2 G12) (merge-join G2 G9 G10 inner-join,+1,+10) (lookup-join G2 G10 xyz@xy,keyCols=[1],outCols=(1-3,10-12)) (merge-join G9 G2 G10 inner-join,+10,+1) (lookup-join G9 G10 abc@ab,keyCols=[10],outCols=(1-3,10-12)) │ ├── [ordering: +(1|10)] │ │ ├── best: (merge-join G2="[ordering: +1]" G9="[ordering: +10]" G10 inner-join,+1,+10) - │ │ └── cost: 2199.43 + │ │ └── cost: 2220.83 │ └── [] │ ├── best: (merge-join G2="[ordering: +1]" G9="[ordering: +10]" G10 inner-join,+1,+10) - │ └── cost: 2199.43 + │ └── cost: 2220.83 ├── G7: (filters G13) ├── G8: (inner-join G2 G5 G4) (inner-join G5 G2 G4) (merge-join G2 G5 G10 inner-join,+1,+6) (lookup-join G2 G10 stu,keyCols=[1],outCols=(1-3,6-8)) (merge-join G5 G2 G10 inner-join,+6,+1) (lookup-join G5 G10 abc@ab,keyCols=[6],outCols=(1-3,6-8)) │ ├── [ordering: +(1|6)] │ │ ├── best: (merge-join G2="[ordering: +1]" G5="[ordering: +6]" G10 inner-join,+1,+6) - │ │ └── cost: 11909.33 + │ │ └── cost: 11930.63 │ └── [] │ ├── best: (merge-join G2="[ordering: +1]" G5="[ordering: +6]" G10 inner-join,+1,+6) - │ └── cost: 11909.33 + │ └── cost: 11930.63 ├── G9: (scan xyz,cols=(10-12)) (scan xyz@xy,cols=(10-12)) (scan xyz@yz,cols=(10-12)) │ ├── [ordering: +10] │ │ ├── best: (scan xyz@xy,cols=(10-12)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan xyz,cols=(10-12)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G10: (filters) ├── G11: (eq G14 G15) ├── G12: (filters G16) @@ -302,74 +302,74 @@ memo (optimized, ~37KB, required=[presentation: pid1:1,cid1:2,gcid1:3,gca1:4,ca1 ├── G1: (project G2 G3 pid1 cid1 gcid1 gca1 ca1 pa1) │ ├── [presentation: pid1:1,cid1:2,gcid1:3,gca1:4,ca1:8,pa1:11] [ordering: +1] │ │ ├── best: (project G2="[ordering: +(1|6|10)]" G3 pid1 cid1 gcid1 gca1 ca1 pa1) - │ │ └── cost: 2796.45 + │ │ └── cost: 2817.85 │ └── [] │ ├── best: (project G2 G3 pid1 cid1 gcid1 gca1 ca1 pa1) - │ └── cost: 2796.45 + │ └── cost: 2817.85 ├── G2: (inner-join G4 G5 G6) (inner-join G7 G8 G9) (inner-join G8 G7 G9) (inner-join G10 G11 G9) (inner-join G11 G10 G9) (inner-join G4 G5 G6) (inner-join G5 G4 G6) (merge-join G4 G5 G12 inner-join,+1,+10) (lookup-join G4 G12 parent1,keyCols=[1],outCols=(1-4,6-8,10,11)) (merge-join G7 G8 G12 inner-join,+1,+2,+6,+7) (merge-join G8 G7 G12 inner-join,+6,+7,+1,+2) (lookup-join G8 G12 grandchild1,keyCols=[6 7],outCols=(1-4,6-8,10,11)) (merge-join G10 G11 G12 inner-join,+6,+7,+1,+2) (merge-join G11 G10 G12 inner-join,+1,+2,+6,+7) (lookup-join G11 G12 child1,keyCols=[1 2],outCols=(1-4,6-8,10,11)) (merge-join G4 G5 G12 inner-join,+1,+10) (lookup-join G4 G12 parent1,keyCols=[1],outCols=(1-4,6-8,10,11)) (merge-join G5 G4 G12 inner-join,+10,+1) │ ├── [ordering: +(1|6|10)] │ │ ├── best: (lookup-join G4="[ordering: +(1|6)]" G12 parent1,keyCols=[1],outCols=(1-4,6-8,10,11)) - │ │ └── cost: 2795.44 + │ │ └── cost: 2816.84 │ └── [] │ ├── best: (lookup-join G4 G12 parent1,keyCols=[1],outCols=(1-4,6-8,10,11)) - │ └── cost: 2795.44 + │ └── cost: 2816.84 ├── G3: (projections) ├── G4: (inner-join G7 G10 G9) (inner-join G7 G10 G9) (inner-join G10 G7 G9) (merge-join G7 G10 G12 inner-join,+1,+2,+6,+7) (lookup-join G7 G12 child1,keyCols=[1 2],outCols=(1-4,6-8)) (merge-join G7 G10 G12 inner-join,+1,+2,+6,+7) (lookup-join G7 G12 child1,keyCols=[1 2],outCols=(1-4,6-8)) (merge-join G10 G7 G12 inner-join,+6,+7,+1,+2) (lookup-join G10 G12 grandchild1,keyCols=[6 7],outCols=(1-4,6-8)) │ ├── [ordering: +(1|6)] │ │ ├── best: (merge-join G7="[ordering: +1,+2]" G10="[ordering: +6,+7]" G12 inner-join,+1,+2,+6,+7) - │ │ └── cost: 2190.43 + │ │ └── cost: 2211.83 │ └── [] │ ├── best: (merge-join G7="[ordering: +1,+2]" G10="[ordering: +6,+7]" G12 inner-join,+1,+2,+6,+7) - │ └── cost: 2190.43 + │ └── cost: 2211.83 ├── G5: (scan parent1,cols=(10,11)) │ ├── [ordering: +10] │ │ ├── best: (scan parent1,cols=(10,11)) - │ │ └── cost: 1054.41 + │ │ └── cost: 1064.81 │ └── [] │ ├── best: (scan parent1,cols=(10,11)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G6: (filters G13) ├── G7: (scan grandchild1,cols=(1-4)) │ ├── [ordering: +1,+2] │ │ ├── best: (scan grandchild1,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ ├── [ordering: +1] │ │ ├── best: (scan grandchild1,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ └── [] │ ├── best: (scan grandchild1,cols=(1-4)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── G8: (inner-join G10 G5 G14) (inner-join G5 G10 G14) (merge-join G10 G5 G12 inner-join,+6,+10) (lookup-join G10 G12 parent1,keyCols=[6],outCols=(6-8,10,11)) (merge-join G5 G10 G12 inner-join,+10,+6) (lookup-join G5 G12 child1,keyCols=[10],outCols=(6-8,10,11)) │ ├── [ordering: +(6|10),+7] │ │ ├── best: (sort G8) - │ │ └── cost: 2439.32 + │ │ └── cost: 2460.32 │ ├── [ordering: +(6|10)] │ │ ├── best: (merge-join G10="[ordering: +6]" G5="[ordering: +10]" G12 inner-join,+6,+10) - │ │ └── cost: 2159.03 + │ │ └── cost: 2180.03 │ └── [] │ ├── best: (merge-join G10="[ordering: +6]" G5="[ordering: +10]" G12 inner-join,+6,+10) - │ └── cost: 2159.03 + │ └── cost: 2180.03 ├── G9: (filters G15 G16) ├── G10: (scan child1,cols=(6-8)) │ ├── [ordering: +6,+7] │ │ ├── best: (scan child1,cols=(6-8)) - │ │ └── cost: 1074.61 + │ │ └── cost: 1085.21 │ ├── [ordering: +6] │ │ ├── best: (scan child1,cols=(6-8)) - │ │ └── cost: 1074.61 + │ │ └── cost: 1085.21 │ └── [] │ ├── best: (scan child1,cols=(6-8)) - │ └── cost: 1074.61 + │ └── cost: 1085.21 ├── G11: (inner-join G7 G5 G6) (inner-join G5 G7 G6) (merge-join G7 G5 G12 inner-join,+1,+10) (lookup-join G7 G12 parent1,keyCols=[1],outCols=(1-4,10,11)) (merge-join G5 G7 G12 inner-join,+10,+1) (lookup-join G5 G12 grandchild1,keyCols=[10],outCols=(1-4,10,11)) │ ├── [ordering: +(1|10),+2] │ │ ├── best: (sort G11) - │ │ └── cost: 2469.52 + │ │ └── cost: 2490.72 │ ├── [ordering: +(1|10)] │ │ ├── best: (merge-join G7="[ordering: +1]" G5="[ordering: +10]" G12 inner-join,+1,+10) - │ │ └── cost: 2179.23 + │ │ └── cost: 2200.43 │ └── [] │ ├── best: (merge-join G7="[ordering: +1]" G5="[ordering: +10]" G12 inner-join,+1,+10) - │ └── cost: 2179.23 + │ └── cost: 2200.43 ├── G12: (filters) ├── G13: (eq G17 G18) ├── G14: (filters G19) @@ -390,38 +390,38 @@ memo (optimized, ~24KB, required=[presentation: a:1,b:2,c:3,s:6,t:7,u:8,x:10,y:1 ├── G1: (inner-join G2 G3 G4) (inner-join G2 G3 G4) (inner-join G3 G2 G4) │ └── [presentation: a:1,b:2,c:3,s:6,t:7,u:8,x:10,y:11,z:12,p:15,q:16,r:17,s:18,t:19] │ ├── best: (inner-join G3 G2 G4) - │ └── cost: 325035524.46 + │ └── cost: 325035567.46 ├── G2: (select G5 G6) (scan abc@ab,cols=(1-3),constrained) │ └── [] │ ├── best: (scan abc@ab,cols=(1-3),constrained) - │ └── cost: 5.08 + │ └── cost: 15.78 ├── G3: (inner-join G7 G8 G4) (inner-join G7 G8 G4) (inner-join G8 G7 G4) │ └── [] │ ├── best: (inner-join G8 G7 G4) - │ └── cost: 100035519.35 + │ └── cost: 100035551.65 ├── G4: (filters) ├── G5: (scan abc,cols=(1-3)) (scan abc@ab,cols=(1-3)) (scan abc@bc,cols=(1-3)) │ └── [] │ ├── best: (scan abc,cols=(1-3)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G6: (filters G9) ├── G7: (scan stu,cols=(6-8)) (scan stu@uts,cols=(6-8)) │ └── [] │ ├── best: (scan stu,cols=(6-8)) - │ └── cost: 10614.61 + │ └── cost: 10625.21 ├── G8: (inner-join G10 G11 G4) (inner-join G10 G11 G4) (inner-join G11 G10 G4) │ └── [] │ ├── best: (inner-join G10 G11 G4) - │ └── cost: 12229.73 + │ └── cost: 12251.43 ├── G9: (eq G12 G13) ├── G10: (scan xyz,cols=(10-12)) (scan xyz@xy,cols=(10-12)) (scan xyz@yz,cols=(10-12)) │ └── [] │ ├── best: (scan xyz,cols=(10-12)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G11: (scan pqr,cols=(15-19)) │ └── [] │ ├── best: (scan pqr,cols=(15-19)) - │ └── cost: 1115.01 + │ └── cost: 1126.01 ├── G12: (variable a) └── G13: (const 1) @@ -436,53 +436,53 @@ memo (optimized, ~34KB, required=[presentation: s:1,t:2,u:3,a:5,b:6,c:7,x:10,y:1 ├── G1: (inner-join G2 G3 G4) (inner-join G2 G3 G4) (inner-join G3 G2 G4) (merge-join G2 G3 G5 inner-join,+3,+5) (merge-join G2 G3 G5 inner-join,+3,+5) (merge-join G3 G2 G5 inner-join,+5,+3) (lookup-join G3 G5 stu@uts,keyCols=[5],outCols=(1-3,5-7,10-12,15-19)) │ └── [presentation: s:1,t:2,u:3,a:5,b:6,c:7,x:10,y:11,z:12,p:15,q:16,r:17,s:18,t:19] │ ├── best: (merge-join G2="[ordering: +3]" G3="[ordering: +(5|10|15)]" G5 inner-join,+3,+5) - │ └── cost: 14169.07 + │ └── cost: 14212.07 ├── G2: (scan stu,cols=(1-3)) (scan stu@uts,cols=(1-3)) │ ├── [ordering: +3] │ │ ├── best: (scan stu@uts,cols=(1-3)) - │ │ └── cost: 10614.61 + │ │ └── cost: 10625.21 │ └── [] │ ├── best: (scan stu,cols=(1-3)) - │ └── cost: 10614.61 + │ └── cost: 10625.21 ├── G3: (inner-join G6 G7 G8) (inner-join G6 G7 G8) (inner-join G7 G6 G8) (merge-join G6 G7 G5 inner-join,+5,+10) (merge-join G6 G7 G5 inner-join,+5,+10) (merge-join G7 G6 G5 inner-join,+10,+5) (lookup-join G7 G5 abc@ab,keyCols=[10],outCols=(5-7,10-12,15-19)) │ ├── [ordering: +(5|10|15)] │ │ ├── best: (merge-join G6="[ordering: +5]" G7="[ordering: +(10|15)]" G5 inner-join,+5,+10) - │ │ └── cost: 3344.45 + │ │ └── cost: 3376.85 │ └── [] │ ├── best: (merge-join G6="[ordering: +5]" G7="[ordering: +(10|15)]" G5 inner-join,+5,+10) - │ └── cost: 3344.45 + │ └── cost: 3376.85 ├── G4: (filters G9) ├── G5: (filters) ├── G6: (scan abc,cols=(5-7)) (scan abc@ab,cols=(5-7)) (scan abc@bc,cols=(5-7)) │ ├── [ordering: +5] │ │ ├── best: (scan abc@ab,cols=(5-7)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan abc,cols=(5-7)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G7: (inner-join G10 G11 G12) (inner-join G10 G11 G12) (inner-join G11 G10 G12) (merge-join G10 G11 G5 inner-join,+10,+15) (lookup-join G10 G5 pqr,keyCols=[10],outCols=(10-12,15-19)) (merge-join G10 G11 G5 inner-join,+10,+15) (lookup-join G10 G5 pqr,keyCols=[10],outCols=(10-12,15-19)) (merge-join G11 G10 G5 inner-join,+15,+10) (lookup-join G11 G5 xyz@xy,keyCols=[15],outCols=(10-12,15-19)) │ ├── [ordering: +(10|15)] │ │ ├── best: (merge-join G10="[ordering: +10]" G11="[ordering: +15]" G5 inner-join,+10,+15) - │ │ └── cost: 2229.73 + │ │ └── cost: 2251.43 │ └── [] │ ├── best: (merge-join G10="[ordering: +10]" G11="[ordering: +15]" G5 inner-join,+10,+15) - │ └── cost: 2229.73 + │ └── cost: 2251.43 ├── G8: (filters G13) ├── G9: (eq G14 G15) ├── G10: (scan xyz,cols=(10-12)) (scan xyz@xy,cols=(10-12)) (scan xyz@yz,cols=(10-12)) │ ├── [ordering: +10] │ │ ├── best: (scan xyz@xy,cols=(10-12)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan xyz,cols=(10-12)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G11: (scan pqr,cols=(15-19)) │ ├── [ordering: +15] │ │ ├── best: (scan pqr,cols=(15-19)) - │ │ └── cost: 1115.01 + │ │ └── cost: 1126.01 │ └── [] │ ├── best: (scan pqr,cols=(15-19)) - │ └── cost: 1115.01 + │ └── cost: 1126.01 ├── G12: (filters G16) ├── G13: (eq G15 G17) ├── G14: (variable u) @@ -530,11 +530,11 @@ memo (optimized, ~14KB, required=[presentation: a:1,b:2,c:3,v:6,s:7,t:8,u:9]) ├── G1: (inner-join-apply G2 G3 G4) │ └── [presentation: a:1,b:2,c:3,v:6,s:7,t:8,u:9] │ ├── best: (inner-join-apply G2 G3 G4) - │ └── cost: 1179.22 + │ └── cost: 1189.92 ├── G2: (scan abc,cols=(1-3)) (scan abc@ab,cols=(1-3)) (scan abc@bc,cols=(1-3)) │ └── [] │ ├── best: (scan abc,cols=(1-3)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G3: (inner-join G5 G6 G7) (inner-join G5 G6 G7) (inner-join G6 G5 G7) (lookup-join G5 G8 stu,keyCols=[6],outCols=(6-9)) (lookup-join G5 G8 stu,keyCols=[6],outCols=(6-9)) (merge-join G6 G5 G8 inner-join,+7,+6) │ └── [] │ ├── best: (lookup-join G5 G8 stu,keyCols=[6],outCols=(6-9)) @@ -550,10 +550,10 @@ memo (optimized, ~14KB, required=[presentation: a:1,b:2,c:3,v:6,s:7,t:8,u:9]) ├── G6: (scan stu,cols=(7-9)) (scan stu@uts,cols=(7-9)) │ ├── [ordering: +7] │ │ ├── best: (scan stu,cols=(7-9)) - │ │ └── cost: 10614.61 + │ │ └── cost: 10625.21 │ └── [] │ ├── best: (scan stu,cols=(7-9)) - │ └── cost: 10614.61 + │ └── cost: 10625.21 ├── G7: (filters G11) ├── G8: (filters) ├── G9: (eq G12 G13) @@ -1523,21 +1523,21 @@ memo (optimized, ~11KB, required=[presentation: a:1,b:2,c:3,x:6,y:7,z:8]) ├── G1: (inner-join G2 G3 G4) (inner-join G2 G3 G4) (inner-join G3 G2 G4) (merge-join G2 G3 G5 inner-join,+1,+8) (merge-join G2 G3 G5 inner-join,+1,+8) (lookup-join G3 G5 abc@ab,keyCols=[8],outCols=(1-3,6-8)) │ └── [presentation: a:1,b:2,c:3,x:6,y:7,z:8] │ ├── best: (inner-join G2 G3 G4) - │ └── cost: 2209.34 + │ └── cost: 2230.74 ├── G2: (scan abc,cols=(1-3)) (scan abc@ab,cols=(1-3)) (scan abc@bc,cols=(1-3)) │ ├── [ordering: +1] │ │ ├── best: (scan abc@ab,cols=(1-3)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan abc,cols=(1-3)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G3: (scan xyz,cols=(6-8)) (scan xyz@xy,cols=(6-8)) (scan xyz@yz,cols=(6-8)) │ ├── [ordering: +8] │ │ ├── best: (sort G3) - │ │ └── cost: 1334.04 + │ │ └── cost: 1344.74 │ └── [] │ ├── best: (scan xyz,cols=(6-8)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G4: (filters G6) ├── G5: (filters) ├── G6: (eq G7 G8) @@ -1551,21 +1551,21 @@ memo (optimized, ~10KB, required=[presentation: a:1,b:2,c:3,x:6,y:7,z:8]) ├── G1: (full-join G2 G3 G4) (full-join G2 G3 G4) (full-join G3 G2 G4) (merge-join G2 G3 G5 full-join,+1,+8) (merge-join G2 G3 G5 full-join,+1,+8) │ └── [presentation: a:1,b:2,c:3,x:6,y:7,z:8] │ ├── best: (full-join G2 G3 G4) - │ └── cost: 2209.44 + │ └── cost: 2230.84 ├── G2: (scan abc,cols=(1-3)) (scan abc@ab,cols=(1-3)) (scan abc@bc,cols=(1-3)) │ ├── [ordering: +1] │ │ ├── best: (scan abc@ab,cols=(1-3)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan abc,cols=(1-3)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G3: (scan xyz,cols=(6-8)) (scan xyz@xy,cols=(6-8)) (scan xyz@yz,cols=(6-8)) │ ├── [ordering: +8] │ │ ├── best: (sort G3) - │ │ └── cost: 1334.04 + │ │ └── cost: 1344.74 │ └── [] │ ├── best: (scan xyz,cols=(6-8)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G4: (filters G6) ├── G5: (filters) ├── G6: (eq G7 G8) @@ -1637,15 +1637,15 @@ memo (optimized, ~10KB, required=[presentation: a:1,b:2,c:3,x:6,y:7,z:8]) ├── G1: (inner-join G2 G3 G4) (lookup-join G2 G5 xyz@xy,keyCols=[1],outCols=(1-3,6-8)) │ └── [presentation: a:1,b:2,c:3,x:6,y:7,z:8] │ ├── best: (lookup-join G2 G5 xyz@xy,keyCols=[1],outCols=(1-3,6-8)) - │ └── cost: 23164.72 + │ └── cost: 23175.42 ├── G2: (scan abc,cols=(1-3)) (scan abc@ab,cols=(1-3)) (scan abc@bc,cols=(1-3)) │ └── [] │ ├── best: (scan abc,cols=(1-3)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G3: (scan xyz,cols=(6-8)) (scan xyz@xy,cols=(6-8)) (scan xyz@yz,cols=(6-8)) │ └── [] │ ├── best: (scan xyz,cols=(6-8)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G4: (filters G6) ├── G5: (filters) ├── G6: (eq G7 G8) @@ -1741,21 +1741,21 @@ memo (optimized, ~10KB, required=[presentation: a:1,b:2,c:3,x:6,y:7,z:8]) ├── G1: (left-join G2 G3 G4) (left-join G2 G3 G4) (right-join G3 G2 G4) (merge-join G2 G3 G5 left-join,+1,+8) (right-join G3 G2 G4) (merge-join G2 G3 G5 left-join,+1,+8) │ └── [presentation: a:1,b:2,c:3,x:6,y:7,z:8] │ ├── best: (left-join G2 G3 G4) - │ └── cost: 2209.44 + │ └── cost: 2230.84 ├── G2: (scan abc,cols=(1-3)) (scan abc@ab,cols=(1-3)) (scan abc@bc,cols=(1-3)) │ ├── [ordering: +1] │ │ ├── best: (scan abc@ab,cols=(1-3)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan abc,cols=(1-3)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G3: (scan xyz,cols=(6-8)) (scan xyz@xy,cols=(6-8)) (scan xyz@yz,cols=(6-8)) │ ├── [ordering: +8] │ │ ├── best: (sort G3) - │ │ └── cost: 1334.04 + │ │ └── cost: 1344.74 │ └── [] │ ├── best: (scan xyz,cols=(6-8)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G4: (filters G6) ├── G5: (filters) ├── G6: (eq G7 G8) @@ -1788,21 +1788,21 @@ memo (optimized, ~12KB, required=[presentation: a:1,b:2,c:3,x:6,y:7,z:8]) ├── G1: (left-join G2 G3 G4) (left-join G2 G3 G4) (right-join G3 G2 G4) (lookup-join G2 G5 abc@ab,keyCols=[8],outCols=(1-3,6-8)) (right-join G3 G2 G4) (lookup-join G2 G5 abc@ab,keyCols=[8],outCols=(1-3,6-8)) (merge-join G3 G2 G5 right-join,+1,+8) (merge-join G3 G2 G5 right-join,+1,+8) │ └── [presentation: a:1,b:2,c:3,x:6,y:7,z:8] │ ├── best: (left-join G2 G3 G4) - │ └── cost: 2209.44 + │ └── cost: 2230.84 ├── G2: (scan xyz,cols=(6-8)) (scan xyz@xy,cols=(6-8)) (scan xyz@yz,cols=(6-8)) │ ├── [ordering: +8] │ │ ├── best: (sort G2) - │ │ └── cost: 1334.04 + │ │ └── cost: 1344.74 │ └── [] │ ├── best: (scan xyz,cols=(6-8)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G3: (scan abc,cols=(1-3)) (scan abc@ab,cols=(1-3)) (scan abc@bc,cols=(1-3)) │ ├── [ordering: +1] │ │ ├── best: (scan abc@ab,cols=(1-3)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan abc,cols=(1-3)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G4: (filters G6) ├── G5: (filters) ├── G6: (eq G7 G8) @@ -1915,13 +1915,13 @@ semi-join (lookup t.public.def) ├── key columns: [1 3] = [6 7] ├── lookup columns are key ├── stats: [rows=100, distinct(1)=100, null(1)=0, distinct(3)=10, null(3)=0] - ├── cost: 521.740394 + ├── cost: 532.440394 ├── prune: (2) ├── interesting orderings: (+1,+2) (+2,+3) ├── scan t.public.abc │ ├── columns: t.public.abc.a:1(int) t.public.abc.b:2(int) t.public.abc.c:3(int) │ ├── stats: [rows=100, distinct(1)=100, null(1)=0, distinct(3)=10, null(3)=1] - │ ├── cost: 121.71 + │ ├── cost: 132.41 │ ├── prune: (1-3) │ ├── interesting orderings: (+1,+2) (+2,+3) │ └── unfiltered-cols: (1-5) @@ -1938,13 +1938,13 @@ semi-join (lookup t.public.def) ├── key columns: [1 3] = [6 7] ├── lookup columns are key ├── stats: [rows=100, distinct(1)=100, null(1)=0, distinct(3)=10, null(3)=0] - ├── cost: 521.740394 + ├── cost: 532.440394 ├── prune: (2) ├── interesting orderings: (+1,+2) (+2,+3) ├── scan t.public.abc │ ├── columns: t.public.abc.a:1(int) t.public.abc.b:2(int) t.public.abc.c:3(int) │ ├── stats: [rows=100, distinct(1)=100, null(1)=0, distinct(3)=10, null(3)=1] - │ ├── cost: 121.71 + │ ├── cost: 132.41 │ ├── prune: (1-3) │ ├── interesting orderings: (+1,+2) (+2,+3) │ └── unfiltered-cols: (1-5) @@ -2072,21 +2072,21 @@ memo (optimized, ~14KB, required=[presentation: a:1,b:2,c:3,x:6,y:7,z:8]) ├── G1: (inner-join G2 G3 G4) (inner-join G2 G3 G4) (inner-join G3 G2 G4) (merge-join G2 G3 G5 inner-join,+1,+6) (lookup-join G2 G5 xyz@xy,keyCols=[1],outCols=(1-3,6-8)) (merge-join G2 G3 G5 inner-join,+1,+6) (lookup-join G2 G5 xyz@xy,keyCols=[1],outCols=(1-3,6-8)) (merge-join G3 G2 G5 inner-join,+6,+1) (lookup-join G3 G5 abc@ab,keyCols=[6],outCols=(1-3,6-8)) │ └── [presentation: a:1,b:2,c:3,x:6,y:7,z:8] │ ├── best: (merge-join G2="[ordering: +1]" G3="[ordering: +6]" G5 inner-join,+1,+6) - │ └── cost: 1218.43 + │ └── cost: 1239.83 ├── G2: (scan abc,cols=(1-3)) (scan abc@ab,cols=(1-3)) (scan abc@bc,cols=(1-3)) │ ├── [ordering: +1] │ │ ├── best: (scan abc@ab,cols=(1-3)) - │ │ └── cost: 121.71 + │ │ └── cost: 132.41 │ └── [] │ ├── best: (scan abc,cols=(1-3)) - │ └── cost: 121.71 + │ └── cost: 132.41 ├── G3: (scan xyz,cols=(6-8)) (scan xyz@xy,cols=(6-8)) (scan xyz@yz,cols=(6-8)) │ ├── [ordering: +6] │ │ ├── best: (scan xyz@xy,cols=(6-8)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan xyz,cols=(6-8)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G4: (filters G6) ├── G5: (filters) ├── G6: (eq G7 G8) @@ -2101,15 +2101,15 @@ memo (optimized, ~8KB, required=[presentation: a:1,b:2,c:3,x:6,y:7,z:8]) ├── G1: (inner-join G2 G3 G4) │ └── [presentation: a:1,b:2,c:3,x:6,y:7,z:8] │ ├── best: (inner-join G2 G3 G4) - │ └── cost: 1226.19 + │ └── cost: 1247.59 ├── G2: (scan abc,cols=(1-3)) (scan abc@ab,cols=(1-3)) (scan abc@bc,cols=(1-3)) │ └── [] │ ├── best: (scan abc,cols=(1-3)) - │ └── cost: 121.71 + │ └── cost: 132.41 ├── G3: (scan xyz,cols=(6-8)) (scan xyz@xy,cols=(6-8)) (scan xyz@yz,cols=(6-8)) │ └── [] │ ├── best: (scan xyz,cols=(6-8)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G4: (filters G5) ├── G5: (eq G6 G7) ├── G6: (variable a) @@ -2152,20 +2152,16 @@ inner-join (merge) opt SELECT * FROM abc JOIN xyz ON a=x AND b=y WHERE b=1 AND y=1 ---- -inner-join (hash) +inner-join (lookup xyz@xy) ├── columns: a:1!null b:2!null c:3 x:6!null y:7!null z:8 + ├── key columns: [1 2] = [6 7] ├── fd: ()-->(2,7), (1)==(6), (6)==(1), (2)==(7), (7)==(2) - ├── scan xyz@yz - │ ├── columns: x:6 y:7!null z:8 - │ ├── constraint: /7/8/9: [/1 - /1] - │ └── fd: ()-->(7) ├── scan abc@bc │ ├── columns: a:1 b:2!null c:3 │ ├── constraint: /2/3/4: [/1 - /1] │ └── fd: ()-->(2) └── filters - ├── a:1 = x:6 [outer=(1,6), constraints=(/1: (/NULL - ]; /6: (/NULL - ]), fd=(1)==(6), (6)==(1)] - └── b:2 = y:7 [outer=(2,7), constraints=(/2: (/NULL - ]; /7: (/NULL - ]), fd=(2)==(7), (7)==(2)] + └── y:7 = 1 [outer=(7), constraints=(/7: [/1 - /1]; tight), fd=()-->(7)] # Verify case where we generate multiple merge-joins. memo @@ -2175,27 +2171,27 @@ memo (optimized, ~19KB, required=[presentation: s:1,t:2,u:3,s:5,t:6,u:7]) ├── G1: (inner-join G2 G3 G4) (inner-join G2 G3 G4) (inner-join G3 G2 G4) (merge-join G2 G3 G5 inner-join,+1,+2,+3,+5,+6,+7) (merge-join G2 G3 G5 inner-join,+3,+2,+1,+7,+6,+5) (lookup-join G2 G5 stu [as=r],keyCols=[1 2 3],outCols=(1-3,5-7)) (lookup-join G2 G5 stu@uts [as=r],keyCols=[3 2 1],outCols=(1-3,5-7)) (merge-join G2 G3 G5 inner-join,+1,+2,+3,+5,+6,+7) (merge-join G2 G3 G5 inner-join,+3,+2,+1,+7,+6,+5) (lookup-join G2 G5 stu [as=r],keyCols=[1 2 3],outCols=(1-3,5-7)) (lookup-join G2 G5 stu@uts [as=r],keyCols=[3 2 1],outCols=(1-3,5-7)) (merge-join G3 G2 G5 inner-join,+5,+6,+7,+1,+2,+3) (merge-join G3 G2 G5 inner-join,+7,+6,+5,+3,+2,+1) (lookup-join G3 G5 stu [as=l],keyCols=[5 6 7],outCols=(1-3,5-7)) (lookup-join G3 G5 stu@uts [as=l],keyCols=[7 6 5],outCols=(1-3,5-7)) │ └── [presentation: s:1,t:2,u:3,s:5,t:6,u:7] │ ├── best: (merge-join G2="[ordering: +1,+2,+3]" G3="[ordering: +5,+6,+7]" G5 inner-join,+1,+2,+3,+5,+6,+7) - │ └── cost: 21429.23 + │ └── cost: 21450.43 ├── G2: (scan stu [as=l],cols=(1-3)) (scan stu@uts [as=l],cols=(1-3)) │ ├── [ordering: +1,+2,+3] │ │ ├── best: (scan stu [as=l],cols=(1-3)) - │ │ └── cost: 10614.61 + │ │ └── cost: 10625.21 │ ├── [ordering: +3,+2,+1] │ │ ├── best: (scan stu@uts [as=l],cols=(1-3)) - │ │ └── cost: 10614.61 + │ │ └── cost: 10625.21 │ └── [] │ ├── best: (scan stu [as=l],cols=(1-3)) - │ └── cost: 10614.61 + │ └── cost: 10625.21 ├── G3: (scan stu [as=r],cols=(5-7)) (scan stu@uts [as=r],cols=(5-7)) │ ├── [ordering: +5,+6,+7] │ │ ├── best: (scan stu [as=r],cols=(5-7)) - │ │ └── cost: 10614.61 + │ │ └── cost: 10625.21 │ ├── [ordering: +7,+6,+5] │ │ ├── best: (scan stu@uts [as=r],cols=(5-7)) - │ │ └── cost: 10614.61 + │ │ └── cost: 10625.21 │ └── [] │ ├── best: (scan stu [as=r],cols=(5-7)) - │ └── cost: 10614.61 + │ └── cost: 10625.21 ├── G4: (filters G6 G7 G8) ├── G5: (filters) ├── G6: (eq G9 G10) @@ -2436,29 +2432,29 @@ memo (optimized, ~13KB, required=[presentation: a:1,b:2,c:3,x:6,y:7,z:8]) ├── G1: (inner-join G2 G3 G4) (inner-join G2 G3 G4) (inner-join G3 G2 G4) │ └── [presentation: a:1,b:2,c:3,x:6,y:7,z:8] │ ├── best: (inner-join G3 G2 G4) - │ └── cost: 1219.27 + │ └── cost: 1240.67 ├── G2: (select G5 G6) (select G7 G6) (select G8 G6) │ └── [] │ ├── best: (select G7 G6) - │ └── cost: 112.03 + │ └── cost: 122.73 ├── G3: (scan xyz,cols=(6-8)) (scan xyz@xy,cols=(6-8)) (scan xyz@yz,cols=(6-8)) │ └── [] │ ├── best: (scan xyz,cols=(6-8)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G4: (filters) ├── G5: (scan abc,cols=(1-3)) (scan abc@ab,cols=(1-3)) (scan abc@bc,cols=(1-3)) │ └── [] │ ├── best: (scan abc,cols=(1-3)) - │ └── cost: 121.71 + │ └── cost: 132.41 ├── G6: (filters G9) ├── G7: (scan abc@ab,cols=(1-3),constrained) │ └── [] │ ├── best: (scan abc@ab,cols=(1-3),constrained) - │ └── cost: 111.01 + │ └── cost: 121.71 ├── G8: (scan abc@bc,cols=(1-3),constrained) │ └── [] │ ├── best: (scan abc@bc,cols=(1-3),constrained) - │ └── cost: 111.01 + │ └── cost: 121.71 ├── G9: (eq G10 G11) ├── G10: (variable a) └── G11: (variable b) @@ -2474,15 +2470,15 @@ memo (optimized, ~11KB, required=[presentation: a:1,b:2,c:3,k:6]) ├── G1: (inner-join G2 G3 G4) (inner-join G2 G3 G4) (inner-join G3 G2 G4) │ └── [presentation: a:1,b:2,c:3,k:6] │ ├── best: (inner-join G3 G2 G4) - │ └── cost: 2170.19 + │ └── cost: 2191.09 ├── G2: (scan abc,cols=(1-3)) (scan abc@ab,cols=(1-3)) (scan abc@bc,cols=(1-3)) │ └── [] │ ├── best: (scan abc,cols=(1-3)) - │ └── cost: 121.71 + │ └── cost: 132.41 ├── G3: (scan kfloat,cols=(6)) │ └── [] │ ├── best: (scan kfloat,cols=(6)) - │ └── cost: 1034.21 + │ └── cost: 1044.41 ├── G4: (filters G5) ├── G5: (eq G6 G7) ├── G6: (variable a) @@ -3056,15 +3052,15 @@ memo (optimized, ~8KB, required=[presentation: a:5,b:6,n:2,m:1]) ├── G1: (inner-join G2 G3 G4) │ └── [presentation: a:5,b:6,n:2,m:1] │ ├── best: (inner-join G2 G3 G4) - │ └── cost: 1108.15 + │ └── cost: 1129.15 ├── G2: (scan small,cols=(1,2)) │ └── [] │ ├── best: (scan small,cols=(1,2)) - │ └── cost: 25.01 + │ └── cost: 35.51 ├── G3: (scan abcd,cols=(5,6)) (scan abcd@secondary,cols=(5,6)) │ └── [] │ ├── best: (scan abcd@secondary,cols=(5,6)) - │ └── cost: 1064.51 + │ └── cost: 1075.01 ├── G4: (filters G5) ├── G5: (eq G6 G7) ├── G6: (variable a) @@ -4395,14 +4391,14 @@ SELECT m FROM small WHERE EXISTS (SELECT 1 FROM partial_tab WHERE n = i) ---- project ├── columns: m:1 - ├── cost: 245.326 + ├── cost: 255.826 └── semi-join (lookup partial_tab@full_idx) ├── columns: m:1 n:2 ├── key columns: [2] = [6] - ├── cost: 245.216 + ├── cost: 255.716 ├── scan small │ ├── columns: m:1 n:2 - │ └── cost: 25.01 + │ └── cost: 35.51 └── filters (true) opt format=show-cost @@ -4410,14 +4406,14 @@ SELECT m FROM small WHERE EXISTS (SELECT 1 FROM partial_tab WHERE s IN ('foo', ' ---- project ├── columns: m:1 - ├── cost: 245.326 + ├── cost: 255.826 └── semi-join (lookup partial_tab@partial_idx,partial) ├── columns: m:1 n:2 ├── key columns: [2] = [6] - ├── cost: 245.216 + ├── cost: 255.716 ├── scan small │ ├── columns: m:1 n:2 - │ └── cost: 25.01 + │ └── cost: 35.51 └── filters (true) # Regression test for #63735. Ensure that the constant filter which maximally @@ -4592,47 +4588,47 @@ memo (optimized, ~35KB, required=[presentation: name:15,popn_per_sqkm:20]) ├── G1: (project G2 G3 name) │ └── [presentation: name:15,popn_per_sqkm:20] │ ├── best: (project G2 G3 name) - │ └── cost: 7322.84 + │ └── cost: 7333.54 ├── G2: (group-by G4 G5 cols=(15,16)) │ └── [] │ ├── best: (group-by G4 G5 cols=(15,16)) - │ └── cost: 7322.79 + │ └── cost: 7333.49 ├── G3: (projections G6) ├── G4: (inner-join G7 G8 G9) (inner-join G7 G8 G9) (inner-join G8 G7 G9) (lookup-join G10 G11 nyc_neighborhoods [as=n],keyCols=[21],outCols=(3,9,10,14-16)) (lookup-join G12 G11 nyc_neighborhoods [as=n],keyCols=[27],outCols=(3,9,10,14-16)) (lookup-join G13 G9 nyc_census_blocks [as=c],keyCols=[33],outCols=(3,9,10,14-16)) │ └── [] │ ├── best: (lookup-join G13 G9 nyc_census_blocks [as=c],keyCols=[33],outCols=(3,9,10,14-16)) - │ └── cost: 7316.67 + │ └── cost: 7327.37 ├── G5: (aggregations G14) ├── G6: (div G15 G16) ├── G7: (scan nyc_census_blocks [as=c],cols=(3,9,10)) │ └── [] │ ├── best: (scan nyc_census_blocks [as=c],cols=(3,9,10)) - │ └── cost: 43852.53 + │ └── cost: 43863.83 ├── G8: (select G17 G18) │ └── [] │ ├── best: (select G17 G18) - │ └── cost: 154.05 + │ └── cost: 164.75 ├── G9: (filters G19 G20) ├── G10: (inverted-join G7 G21 nyc_neighborhoods@nyc_neighborhoods_geo_idx [as=n]) │ └── [] │ ├── best: (inverted-join G7 G21 nyc_neighborhoods@nyc_neighborhoods_geo_idx [as=n]) - │ └── cost: 921822.83 + │ └── cost: 921834.13 ├── G11: (filters G19 G20 G22) ├── G12: (inverted-join G7 G21 nyc_neighborhoods@nyc_neighborhoods_geo_idx [as=n]) │ └── [] │ ├── best: (inverted-join G7 G21 nyc_neighborhoods@nyc_neighborhoods_geo_idx [as=n]) - │ └── cost: 921822.83 + │ └── cost: 921834.13 ├── G13: (inverted-join G8 G21 nyc_census_blocks@nyc_census_blocks_geo_idx [as=c]) │ └── [] │ ├── best: (inverted-join G8 G21 nyc_census_blocks@nyc_census_blocks_geo_idx [as=c]) - │ └── cost: 1776.86 + │ └── cost: 1787.56 ├── G14: (sum G23) ├── G15: (variable sum) ├── G16: (div G24 G25) ├── G17: (scan nyc_neighborhoods [as=n],cols=(14-16)) │ └── [] │ ├── best: (scan nyc_neighborhoods [as=n],cols=(14-16)) - │ └── cost: 152.74 + │ └── cost: 163.44 ├── G18: (filters G22) ├── G19: (function G26 st_intersects) ├── G20: (eq G27 G28) diff --git a/pkg/sql/opt/xform/testdata/rules/join_order b/pkg/sql/opt/xform/testdata/rules/join_order index 3574729f7186..eeb22a5a754d 100644 --- a/pkg/sql/opt/xform/testdata/rules/join_order +++ b/pkg/sql/opt/xform/testdata/rules/join_order @@ -361,27 +361,27 @@ memo (optimized, ~24KB, required=[presentation: b:1,x:2,c:4,y:5,a:7,b:8,c:9,d:10 ├── G1: (inner-join G2 G3 G4) (merge-join G2 G3 G5 inner-join,+1,+8) │ └── [presentation: b:1,x:2,c:4,y:5,a:7,b:8,c:9,d:10] │ ├── best: (merge-join G2="[ordering: +1]" G3 G5 inner-join,+1,+8) - │ └── cost: 2133.97 + │ └── cost: 2154.77 ├── G2: (scan bx,cols=(1,2)) │ ├── [ordering: +1] │ │ ├── best: (scan bx,cols=(1,2)) - │ │ └── cost: 1054.41 + │ │ └── cost: 1064.81 │ └── [] │ ├── best: (scan bx,cols=(1,2)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G3: (inner-join G6 G7 G8) (merge-join G6 G7 G5 inner-join,+4,+9) (lookup-join G9 G8 abc,keyCols=[12],outCols=(4,5,7-10)) │ └── [] │ ├── best: (merge-join G6="[ordering: +4]" G7 G5 inner-join,+4,+9) - │ └── cost: 1069.53 + │ └── cost: 1079.93 ├── G4: (filters G10) ├── G5: (filters) ├── G6: (scan cy,cols=(4,5)) │ ├── [ordering: +4] │ │ ├── best: (scan cy,cols=(4,5)) - │ │ └── cost: 1054.41 + │ │ └── cost: 1064.81 │ └── [] │ ├── best: (scan cy,cols=(4,5)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G7: (select G11 G12) (scan abc,cols=(7-10),constrained) │ └── [] │ ├── best: (scan abc,cols=(7-10),constrained) @@ -390,12 +390,12 @@ memo (optimized, ~24KB, required=[presentation: b:1,x:2,c:4,y:5,a:7,b:8,c:9,d:10 ├── G9: (project G6 G14 c y) │ └── [] │ ├── best: (project G6 G14 c y) - │ └── cost: 1074.42 + │ └── cost: 1084.82 ├── G10: (eq G15 G16) ├── G11: (scan abc,cols=(7-10)) │ └── [] │ ├── best: (scan abc,cols=(7-10)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── G12: (filters G17) ├── G13: (eq G18 G19) ├── G14: (projections G20) @@ -418,10 +418,10 @@ memo (optimized, ~43KB, required=[presentation: b:1,x:2,c:4,y:5,a:7,b:8,c:9,d:10 ├── G2: (scan bx,cols=(1,2)) │ ├── [ordering: +1] │ │ ├── best: (scan bx,cols=(1,2)) - │ │ └── cost: 1054.41 + │ │ └── cost: 1064.81 │ └── [] │ ├── best: (scan bx,cols=(1,2)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G3: (inner-join G5 G9 G7) (inner-join G5 G9 G7) (inner-join G9 G5 G7) (merge-join G5 G9 G8 inner-join,+4,+9) (lookup-join G10 G7 abc,keyCols=[12],outCols=(4,5,7-10)) (merge-join G5 G9 G8 inner-join,+4,+9) (lookup-join G11 G7 abc,keyCols=[13],outCols=(4,5,7-10)) (lookup-join G9 G8 cy,keyCols=[9],outCols=(4,5,7-10)) │ └── [] │ ├── best: (lookup-join G9 G8 cy,keyCols=[9],outCols=(4,5,7-10)) @@ -430,10 +430,10 @@ memo (optimized, ~43KB, required=[presentation: b:1,x:2,c:4,y:5,a:7,b:8,c:9,d:10 ├── G5: (scan cy,cols=(4,5)) │ ├── [ordering: +4] │ │ ├── best: (scan cy,cols=(4,5)) - │ │ └── cost: 1054.41 + │ │ └── cost: 1064.81 │ └── [] │ ├── best: (scan cy,cols=(4,5)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G6: (inner-join G2 G9 G4) (inner-join G9 G2 G4) (merge-join G2 G9 G8 inner-join,+1,+8) (lookup-join G13 G4 abc,keyCols=[14],outCols=(1,2,7-10)) (lookup-join G9 G8 bx,keyCols=[8],outCols=(1,2,7-10)) │ └── [] │ ├── best: (lookup-join G9 G8 bx,keyCols=[8],outCols=(1,2,7-10)) @@ -447,21 +447,21 @@ memo (optimized, ~43KB, required=[presentation: b:1,x:2,c:4,y:5,a:7,b:8,c:9,d:10 ├── G10: (project G5 G17 c y) │ └── [] │ ├── best: (project G5 G17 c y) - │ └── cost: 1074.42 + │ └── cost: 1084.82 ├── G11: (project G5 G17 c y) │ └── [] │ ├── best: (project G5 G17 c y) - │ └── cost: 1074.42 + │ └── cost: 1084.82 ├── G12: (eq G18 G19) ├── G13: (project G2 G17 b x) │ └── [] │ ├── best: (project G2 G17 b x) - │ └── cost: 1074.42 + │ └── cost: 1084.82 ├── G14: (eq G20 G21) ├── G15: (scan abc,cols=(7-10)) │ └── [] │ ├── best: (scan abc,cols=(7-10)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── G16: (filters G22) ├── G17: (projections G23) ├── G18: (variable abc.b) @@ -517,7 +517,7 @@ inner-join (cross) ├── columns: a:1(int!null) b:2(int) c:3(int) d:4(int) b:6(int!null) x:7(int) c:9(int!null) y:10(int) d:12(int!null) z:13(int) ├── multiplicity: left-rows(zero-or-one), right-rows(zero-or-more) ├── stats: [rows=1e+09] - ├── cost: 32525715.9 + ├── cost: 32525747.1 ├── key: (6,9,12) ├── fd: ()-->(1-4), (6)-->(7), (9)-->(10), (12)-->(13) ├── prune: (2-4,6,7,9,10,12,13) @@ -525,7 +525,7 @@ inner-join (cross) ├── inner-join (cross) │ ├── columns: t.public.bx.b:6(int!null) t.public.bx.x:7(int) t.public.cy.c:9(int!null) t.public.cy.y:10(int) t.public.dz.d:12(int!null) t.public.dz.z:13(int) │ ├── stats: [rows=1e+09] - │ ├── cost: 10025710.8 + │ ├── cost: 10025741.9 │ ├── key: (6,9,12) │ ├── fd: (6)-->(7), (9)-->(10), (12)-->(13) │ ├── prune: (6,7,9,10,12,13) @@ -533,7 +533,7 @@ inner-join (cross) │ ├── inner-join (cross) │ │ ├── columns: t.public.cy.c:9(int!null) t.public.cy.y:10(int) t.public.dz.d:12(int!null) t.public.dz.z:13(int) │ │ ├── stats: [rows=1000000] - │ │ ├── cost: 12138.83 + │ │ ├── cost: 12159.63 │ │ ├── key: (9,12) │ │ ├── fd: (9)-->(10), (12)-->(13) │ │ ├── prune: (9,10,12,13) @@ -541,7 +541,7 @@ inner-join (cross) │ │ ├── scan t.public.cy │ │ │ ├── columns: t.public.cy.c:9(int!null) t.public.cy.y:10(int) │ │ │ ├── stats: [rows=1000] - │ │ │ ├── cost: 1054.41 + │ │ │ ├── cost: 1064.81 │ │ │ ├── key: (9) │ │ │ ├── fd: (9)-->(10) │ │ │ ├── prune: (9,10) @@ -550,7 +550,7 @@ inner-join (cross) │ │ ├── scan t.public.dz │ │ │ ├── columns: t.public.dz.d:12(int!null) t.public.dz.z:13(int) │ │ │ ├── stats: [rows=1000] - │ │ │ ├── cost: 1054.41 + │ │ │ ├── cost: 1064.81 │ │ │ ├── key: (12) │ │ │ ├── fd: (12)-->(13) │ │ │ ├── prune: (12,13) @@ -560,7 +560,7 @@ inner-join (cross) │ ├── scan t.public.bx │ │ ├── columns: t.public.bx.b:6(int!null) t.public.bx.x:7(int) │ │ ├── stats: [rows=1000] - │ │ ├── cost: 1054.41 + │ │ ├── cost: 1064.81 │ │ ├── key: (6) │ │ ├── fd: (6)-->(7) │ │ ├── prune: (6,7) @@ -589,53 +589,53 @@ memo (optimized, ~24KB, required=[presentation: b:1,x:2,c:4,y:5,d:7,z:8,a:10,b:1 ├── G1: (inner-join G2 G3 G4) (merge-join G2 G3 G5 inner-join,+2,+5) │ └── [presentation: b:1,x:2,c:4,y:5,d:7,z:8,a:10,b:11,c:12,d:13] │ ├── best: (inner-join G2 G3 G4) - │ └── cost: 5580.15 + │ └── cost: 5622.15 ├── G2: (scan bx,cols=(1,2)) │ ├── [ordering: +2] │ │ ├── best: (sort G2) - │ │ └── cost: 1293.74 + │ │ └── cost: 1304.14 │ └── [] │ ├── best: (scan bx,cols=(1,2)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G3: (inner-join G6 G7 G8) (merge-join G6 G7 G5 inner-join,+5,+8) │ ├── [ordering: +(5|8|10)] │ │ ├── best: (merge-join G6="[ordering: +5]" G7="[ordering: +(8|10)]" G5 inner-join,+5,+8) - │ │ └── cost: 3830.11 + │ │ └── cost: 3861.71 │ └── [] │ ├── best: (inner-join G6 G7 G8) - │ └── cost: 3371.41 + │ └── cost: 3403.01 ├── G4: (filters G9) ├── G5: (filters) ├── G6: (scan cy,cols=(4,5)) │ ├── [ordering: +5] │ │ ├── best: (sort G6) - │ │ └── cost: 1293.74 + │ │ └── cost: 1304.14 │ └── [] │ ├── best: (scan cy,cols=(4,5)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G7: (inner-join G10 G11 G12) (merge-join G10 G11 G5 inner-join,+8,+10) (lookup-join G10 G5 abc,keyCols=[8],outCols=(7,8,10-13)) │ ├── [ordering: +(8|10)] │ │ ├── best: (merge-join G10="[ordering: +8]" G11="[ordering: +10]" G5 inner-join,+8,+10) - │ │ └── cost: 2418.46 + │ │ └── cost: 2439.66 │ └── [] │ ├── best: (inner-join G10 G11 G12) - │ └── cost: 2189.14 + │ └── cost: 2210.34 ├── G8: (filters G13) ├── G9: (eq G14 G15) ├── G10: (scan dz,cols=(7,8)) │ ├── [ordering: +8] │ │ ├── best: (sort G10) - │ │ └── cost: 1293.74 + │ │ └── cost: 1304.14 │ └── [] │ ├── best: (scan dz,cols=(7,8)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G11: (scan abc,cols=(10-13)) │ ├── [ordering: +10] │ │ ├── best: (scan abc,cols=(10-13)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ └── [] │ ├── best: (scan abc,cols=(10-13)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── G12: (filters G16) ├── G13: (eq G15 G17) ├── G14: (variable x) @@ -655,99 +655,99 @@ memo (optimized, ~53KB, required=[presentation: b:1,x:2,c:4,y:5,d:7,z:8,a:10,b:1 ├── G1: (inner-join G2 G3 G4) (inner-join G2 G3 G4) (inner-join G3 G2 G4) (inner-join G5 G6 G7) (inner-join G6 G5 G7) (inner-join G8 G9 G7) (inner-join G9 G8 G7) (inner-join G10 G11 G12) (inner-join G11 G10 G12) (inner-join G13 G14 G12) (inner-join G14 G13 G12) (inner-join G15 G16 G12) (inner-join G16 G15 G12) (inner-join G17 G18 G12) (inner-join G18 G17 G12) (merge-join G11 G10 G19 inner-join,+10,+8) (merge-join G14 G13 G19 inner-join,+10,+8) (merge-join G16 G15 G19 inner-join,+10,+8) (lookup-join G17 G19 abc,keyCols=[8],outCols=(1,2,4,5,7,8,10-13)) (merge-join G18 G17 G19 inner-join,+10,+8) │ └── [presentation: b:1,x:2,c:4,y:5,d:7,z:8,a:10,b:11,c:12,d:13] │ ├── best: (inner-join G3 G2 G4) - │ └── cost: 5536.15 + │ └── cost: 5578.15 ├── G2: (scan bx,cols=(1,2)) │ ├── [ordering: +2] │ │ ├── best: (sort G2) - │ │ └── cost: 1293.74 + │ │ └── cost: 1304.14 │ └── [] │ ├── best: (scan bx,cols=(1,2)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G3: (inner-join G5 G9 G7) (inner-join G5 G9 G7) (inner-join G9 G5 G7) (inner-join G10 G14 G12) (inner-join G14 G10 G12) (inner-join G15 G18 G12) (inner-join G18 G15 G12) (merge-join G14 G10 G19 inner-join,+10,+8) (lookup-join G15 G19 abc,keyCols=[8],outCols=(4,5,7,8,10-13)) (merge-join G18 G15 G19 inner-join,+10,+8) │ └── [] │ ├── best: (inner-join G5 G9 G7) - │ └── cost: 3371.41 + │ └── cost: 3403.01 ├── G4: (filters G20) ├── G5: (scan cy,cols=(4,5)) │ ├── [ordering: +5] │ │ ├── best: (sort G5) - │ │ └── cost: 1293.74 + │ │ └── cost: 1304.14 │ └── [] │ ├── best: (scan cy,cols=(4,5)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G6: (inner-join G2 G9 G21) (inner-join G9 G2 G21) (inner-join G10 G16 G12) (inner-join G16 G10 G12) (inner-join G13 G18 G12) (inner-join G18 G13 G12) (merge-join G16 G10 G19 inner-join,+10,+8) (lookup-join G13 G19 abc,keyCols=[8],outCols=(1,2,7,8,10-13)) (merge-join G18 G13 G19 inner-join,+10,+8) │ └── [] │ ├── best: (inner-join G2 G9 G21) - │ └── cost: 3371.41 + │ └── cost: 3403.01 ├── G7: (filters G22) ├── G8: (inner-join G2 G5 G4) (inner-join G5 G2 G4) │ ├── [ordering: +(2|5)] │ │ ├── best: (sort G8) - │ │ └── cost: 5423.89 + │ │ └── cost: 5444.69 │ └── [] │ ├── best: (inner-join G2 G5 G4) - │ └── cost: 2236.85 + │ └── cost: 2257.65 ├── G9: (inner-join G10 G18 G12) (inner-join G10 G18 G12) (inner-join G18 G10 G12) (lookup-join G10 G19 abc,keyCols=[8],outCols=(7,8,10-13)) (lookup-join G10 G19 abc,keyCols=[8],outCols=(7,8,10-13)) (merge-join G18 G10 G19 inner-join,+10,+8) │ └── [] │ ├── best: (inner-join G10 G18 G12) - │ └── cost: 2189.14 + │ └── cost: 2210.34 ├── G10: (scan dz,cols=(7,8)) │ ├── [ordering: +8] │ │ ├── best: (sort G10) - │ │ └── cost: 1293.74 + │ │ └── cost: 1304.14 │ └── [] │ ├── best: (scan dz,cols=(7,8)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G11: (inner-join G2 G14 G4) (inner-join G14 G2 G4) (inner-join G5 G16 G4) (inner-join G16 G5 G4) (inner-join G8 G18 G23) (inner-join G18 G8 G23) (lookup-join G8 G19 abc,keyCols=[5],outCols=(1,2,4,5,10-13)) (merge-join G18 G8 G19 inner-join,+10,+5) │ ├── [ordering: +(2|5|10)] │ │ ├── best: (merge-join G18="[ordering: +10]" G8="[ordering: +(2|5)]" G19 inner-join,+10,+5) - │ │ └── cost: 6724.73 + │ │ └── cost: 6756.33 │ └── [] │ ├── best: (inner-join G2 G14 G4) - │ └── cost: 3371.41 + │ └── cost: 3403.01 ├── G12: (filters G24) ├── G13: (inner-join G2 G10 G21) (inner-join G10 G2 G21) │ ├── [ordering: +(2|8)] │ │ ├── best: (sort G13) - │ │ └── cost: 5423.89 + │ │ └── cost: 5444.69 │ └── [] │ ├── best: (inner-join G2 G10 G21) - │ └── cost: 2236.85 + │ └── cost: 2257.65 ├── G14: (inner-join G5 G18 G23) (inner-join G18 G5 G23) (lookup-join G5 G19 abc,keyCols=[5],outCols=(4,5,10-13)) (merge-join G18 G5 G19 inner-join,+10,+5) │ ├── [ordering: +(5|10)] │ │ ├── best: (merge-join G18="[ordering: +10]" G5="[ordering: +5]" G19 inner-join,+10,+5) - │ │ └── cost: 2418.46 + │ │ └── cost: 2439.66 │ └── [] │ ├── best: (inner-join G5 G18 G23) - │ └── cost: 2189.14 + │ └── cost: 2210.34 ├── G15: (inner-join G5 G10 G7) (inner-join G10 G5 G7) │ ├── [ordering: +(5|8)] │ │ ├── best: (sort G15) - │ │ └── cost: 5423.89 + │ │ └── cost: 5444.69 │ └── [] │ ├── best: (inner-join G5 G10 G7) - │ └── cost: 2236.85 + │ └── cost: 2257.65 ├── G16: (inner-join G2 G18 G25) (inner-join G18 G2 G25) (lookup-join G2 G19 abc,keyCols=[2],outCols=(1,2,10-13)) (merge-join G18 G2 G19 inner-join,+10,+2) │ ├── [ordering: +(2|10)] │ │ ├── best: (merge-join G18="[ordering: +10]" G2="[ordering: +2]" G19 inner-join,+10,+2) - │ │ └── cost: 2418.46 + │ │ └── cost: 2439.66 │ └── [] │ ├── best: (inner-join G2 G18 G25) - │ └── cost: 2189.14 + │ └── cost: 2210.34 ├── G17: (inner-join G2 G15 G4) (inner-join G15 G2 G4) (inner-join G5 G13 G7) (inner-join G13 G5 G7) (inner-join G8 G10 G7) (inner-join G10 G8 G7) │ ├── [ordering: +(2|5|8)] │ │ ├── best: (sort G17) - │ │ └── cost: 44312.22 + │ │ └── cost: 44343.42 │ └── [] │ ├── best: (inner-join G15 G2 G4) - │ └── cost: 4401.59 + │ └── cost: 4432.79 ├── G18: (scan abc,cols=(10-13)) │ ├── [ordering: +10] │ │ ├── best: (scan abc,cols=(10-13)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ └── [] │ ├── best: (scan abc,cols=(10-13)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── G19: (filters) ├── G20: (eq G26 G27) ├── G21: (filters G28) diff --git a/pkg/sql/opt/xform/testdata/rules/scan b/pkg/sql/opt/xform/testdata/rules/scan index 479e4b9cf672..d2b5493bc394 100644 --- a/pkg/sql/opt/xform/testdata/rules/scan +++ b/pkg/sql/opt/xform/testdata/rules/scan @@ -67,7 +67,7 @@ memo (optimized, ~3KB, required=[presentation: k:1,f:3] [ordering: -1]) │ │ └── cost: 15.71 │ └── [] │ ├── best: (scan a@s_idx,cols=(1,3)) - │ └── cost: 1074.61 + │ └── cost: 1085.21 └── G3: (const 10) @@ -153,10 +153,10 @@ memo (optimized, ~2KB, required=[presentation: k:1] [ordering: +1]) └── G1: (scan a,cols=(1)) (scan a@s_idx,cols=(1)) (scan a@si_idx,cols=(1)) ├── [presentation: k:1] [ordering: +1] │ ├── best: (scan a,cols=(1)) - │ └── cost: 1074.61 + │ └── cost: 1085.21 └── [] ├── best: (scan a@s_idx,cols=(1)) - └── cost: 1064.51 + └── cost: 1075.01 # Scan of secondary index is lowest cost. opt @@ -175,10 +175,10 @@ memo (optimized, ~2KB, required=[presentation: s:4,i:2,f:3] [ordering: +4,+1]) └── G1: (scan a,cols=(1-4)) (scan a@s_idx,cols=(1-4)) ├── [presentation: s:4,i:2,f:3] [ordering: +4,+1] │ ├── best: (scan a@s_idx,cols=(1-4)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 └── [] ├── best: (scan a@s_idx,cols=(1-4)) - └── cost: 1094.81 + └── cost: 1105.61 # No index-join should be generated for a@si_idx, since it is not constrained. exploretrace rule=GenerateIndexScans @@ -229,10 +229,10 @@ memo (optimized, ~2KB, required=[presentation: s:4,i:2,f:3] [ordering: +3]) └── G1: (scan a,cols=(2-4)) (scan a@s_idx,cols=(2-4)) ├── [presentation: s:4,i:2,f:3] [ordering: +3] │ ├── best: (sort G1) - │ └── cost: 1334.04 + │ └── cost: 1344.74 └── [] ├── best: (scan a@s_idx,cols=(2-4)) - └── cost: 1084.71 + └── cost: 1095.41 memo SELECT s, i, f FROM a ORDER BY s DESC, i @@ -241,13 +241,13 @@ memo (optimized, ~2KB, required=[presentation: s:4,i:2,f:3] [ordering: -4,+2]) └── G1: (scan a,cols=(2-4)) (scan a@s_idx,cols=(2-4)) ├── [presentation: s:4,i:2,f:3] [ordering: -4,+2] │ ├── best: (sort G1="[ordering: -4]") - │ └── cost: 1311.81 + │ └── cost: 1323.51 ├── [ordering: -4] │ ├── best: (scan a@s_idx,rev,cols=(2-4)) - │ └── cost: 1185.36 + │ └── cost: 1197.06 └── [] ├── best: (scan a@s_idx,cols=(2-4)) - └── cost: 1084.71 + └── cost: 1095.41 # Force an index in order to ensure that an index join is created. opt @@ -284,14 +284,14 @@ memo (optimized, ~3KB, required=[presentation: d:4] [ordering: +6]) ├── G1: (project G2 G3 d) │ ├── [presentation: d:4] [ordering: +6] │ │ ├── best: (sort G1) - │ │ └── cost: 1323.85 + │ │ └── cost: 1334.35 │ └── [] │ ├── best: (project G2 G3 d) - │ └── cost: 1084.52 + │ └── cost: 1095.02 ├── G2: (scan abc,cols=(4)) │ └── [] │ ├── best: (scan abc,cols=(4)) - │ └── cost: 1064.51 + │ └── cost: 1075.01 ├── G3: (projections G4) ├── G4: (function G5 lower) ├── G5: (scalar-list G6) @@ -314,10 +314,10 @@ memo (optimized, ~2KB, required=[presentation: s:4,i:2,f:3] [ordering: +1]) └── G1: (scan a,cols=(1-4)) (scan a@s_idx,cols=(1-4)) ├── [presentation: s:4,i:2,f:3] [ordering: +1] │ ├── best: (scan a,cols=(1-4)) - │ └── cost: 1104.91 + │ └── cost: 1115.81 └── [] ├── best: (scan a@s_idx,cols=(1-4)) - └── cost: 1094.81 + └── cost: 1105.61 # Secondary index has right order opt @@ -334,10 +334,10 @@ memo (optimized, ~2KB, required=[presentation: s:4,j:5] [ordering: +4]) └── G1: (scan a,cols=(4,5)) (scan a@si_idx,cols=(4,5)) ├── [presentation: s:4,j:5] [ordering: +4] │ ├── best: (scan a@si_idx,rev,cols=(4,5)) - │ └── cost: 1175.26 + │ └── cost: 1186.86 └── [] ├── best: (scan a@si_idx,cols=(4,5)) - └── cost: 1074.61 + └── cost: 1085.21 # Consider three different indexes, and pick index with multiple keys. opt @@ -361,13 +361,13 @@ memo (optimized, ~2KB, required=[presentation: i:2,k:1] [ordering: -4,+2,+1]) └── G1: (scan a,cols=(1,2,4)) (scan a@s_idx,cols=(1,2,4)) (scan a@si_idx,cols=(1,2,4)) ├── [presentation: i:2,k:1] [ordering: -4,+2,+1] │ ├── best: (sort G1="[ordering: -4]") - │ └── cost: 1215.48 + │ └── cost: 1226.18 ├── [ordering: -4] │ ├── best: (scan a@si_idx,cols=(1,2,4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 └── [] ├── best: (scan a@s_idx,cols=(1,2,4)) - └── cost: 1084.71 + └── cost: 1095.41 # GenerateIndexScans propagates row-level locking information. opt diff --git a/pkg/sql/opt/xform/testdata/rules/select b/pkg/sql/opt/xform/testdata/rules/select index 75284e8062e8..935e2c244b1e 100644 --- a/pkg/sql/opt/xform/testdata/rules/select +++ b/pkg/sql/opt/xform/testdata/rules/select @@ -266,39 +266,39 @@ memo (optimized, ~14KB, required=[presentation: i:1,f:2,s:3,b:4]) ├── G1: (select G2 G3) (index-join G4 p,cols=(1-4)) (index-join G5 p,cols=(1-4)) (index-join G6 p,cols=(1-4)) (index-join G7 p,cols=(1-4)) │ └── [presentation: i:1,f:2,s:3,b:4] │ ├── best: (index-join G4 p,cols=(1-4)) - │ └── cost: 49.00 + │ └── cost: 59.80 ├── G2: (scan p,cols=(1-4)) │ └── [] │ ├── best: (scan p,cols=(1-4)) - │ └── cost: 1104.91 + │ └── cost: 1115.81 ├── G3: (filters G8 G9) ├── G4: (select G10 G11) │ └── [] │ ├── best: (select G10 G11) - │ └── cost: 14.93 + │ └── cost: 25.73 ├── G5: (select G12 G13) │ └── [] │ ├── best: (select G12 G13) - │ └── cost: 354.03 + │ └── cost: 364.43 ├── G6: (scan p@idx,partial,cols=(1-3,5),constrained) │ └── [] │ ├── best: (scan p@idx,partial,cols=(1-3,5),constrained) - │ └── cost: 14.09 + │ └── cost: 24.89 ├── G7: (scan p@idx2,partial,cols=(3,5),constrained) │ └── [] │ ├── best: (scan p@idx2,partial,cols=(3,5),constrained) - │ └── cost: 13.72 + │ └── cost: 24.12 ├── G8: (gt G14 G15) ├── G9: (eq G16 G17) ├── G10: (scan p@idx,partial,cols=(1-3,5)) │ └── [] │ ├── best: (scan p@idx,partial,cols=(1-3,5)) - │ └── cost: 14.81 + │ └── cost: 25.61 ├── G11: (filters G8) ├── G12: (scan p@idx2,partial,cols=(3,5)) │ └── [] │ ├── best: (scan p@idx2,partial,cols=(3,5)) - │ └── cost: 350.68 + │ └── cost: 361.08 ├── G13: (filters G9) ├── G14: (variable i) ├── G15: (const 0) @@ -314,16 +314,16 @@ memo (optimized, ~8KB, required=[presentation: i:1]) ├── G1: (project G2 G3 i) │ └── [presentation: i:1] │ ├── best: (project G2 G3 i) - │ └── cost: 1094.84 + │ └── cost: 1105.54 ├── G2: (select G4 G5) │ └── [] │ ├── best: (select G4 G5) - │ └── cost: 1094.73 + │ └── cost: 1105.43 ├── G3: (projections) ├── G4: (scan p,cols=(1,3)) │ └── [] │ ├── best: (scan p,cols=(1,3)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G5: (filters G6) ├── G6: (eq G7 G8) ├── G7: (variable s) @@ -422,7 +422,7 @@ memo (optimized, ~5KB, required=[presentation: k:1]) ├── G2: (scan a,cols=(1)) (scan a@u,cols=(1)) (scan a@v,cols=(1)) │ └── [] │ ├── best: (scan a,cols=(1)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G3: (filters G4) ├── G4: (eq G5 G6) ├── G5: (variable k) @@ -447,16 +447,16 @@ memo (optimized, ~6KB, required=[presentation: k:1]) ├── G1: (project G2 G3 k) │ └── [presentation: k:1] │ ├── best: (project G2 G3 k) - │ └── cost: 354.17 + │ └── cost: 364.67 ├── G2: (select G4 G5) (scan a@v,cols=(1,3),constrained) │ └── [] │ ├── best: (scan a@v,cols=(1,3),constrained) - │ └── cost: 350.86 + │ └── cost: 361.36 ├── G3: (projections) ├── G4: (scan a,cols=(1,3)) (scan a@u,cols=(1,3)) (scan a@v,cols=(1,3)) │ └── [] │ ├── best: (scan a,cols=(1,3)) - │ └── cost: 1064.51 + │ └── cost: 1075.01 ├── G5: (filters G6) ├── G6: (gt G7 G8) ├── G7: (variable v) @@ -484,16 +484,16 @@ memo (optimized, ~7KB, required=[presentation: k:1]) ├── G1: (project G2 G3 k) │ └── [presentation: k:1] │ ├── best: (project G2 G3 k) - │ └── cost: 5.07 + │ └── cost: 5.08 ├── G2: (select G4 G5) (select G6 G7) (scan a@u,cols=(1,2),constrained) │ └── [] │ ├── best: (scan a@u,cols=(1,2),constrained) - │ └── cost: 5.05 + │ └── cost: 5.06 ├── G3: (projections) ├── G4: (scan a,cols=(1,2)) (scan a@u,cols=(1,2)) (scan a@v,cols=(1,2)) │ └── [] │ ├── best: (scan a,cols=(1,2)) - │ └── cost: 1064.51 + │ └── cost: 1075.01 ├── G5: (filters G8 G9) ├── G6: (scan a,cols=(1,2),constrained) │ └── [] @@ -530,16 +530,16 @@ memo (optimized, ~8KB, required=[presentation: k:1]) ├── G1: (project G2 G3 k) │ └── [presentation: k:1] │ ├── best: (project G2 G3 k) - │ └── cost: 5.07 + │ └── cost: 5.08 ├── G2: (select G4 G5) (select G6 G7) (scan a@u,cols=(1,2),constrained) │ └── [] │ ├── best: (scan a@u,cols=(1,2),constrained) - │ └── cost: 5.05 + │ └── cost: 5.06 ├── G3: (projections) ├── G4: (scan a,cols=(1,2)) (scan a@u,cols=(1,2)) (scan a@v,cols=(1,2)) │ └── [] │ ├── best: (scan a,cols=(1,2)) - │ └── cost: 1064.51 + │ └── cost: 1075.01 ├── G5: (filters G8 G9) ├── G6: (scan a,cols=(1,2),constrained) │ └── [] @@ -591,12 +591,12 @@ memo (optimized, ~8KB, required=[presentation: k:1]) ├── G4: (scan a,cols=(1-3)) (scan a@u,cols=(1-3)) (scan a@v,cols=(1-3)) │ └── [] │ ├── best: (scan a,cols=(1-3)) - │ └── cost: 1074.61 + │ └── cost: 1085.21 ├── G5: (filters G10 G11) ├── G6: (scan a@u,cols=(1-3),constrained) │ └── [] │ ├── best: (scan a@u,cols=(1-3),constrained) - │ └── cost: 14.61 + │ └── cost: 25.21 ├── G7: (filters G11) ├── G8: (scan a@v,cols=(1-3),constrained) │ └── [] @@ -678,7 +678,7 @@ memo (optimized, ~5KB, required=[presentation: k:1,u:2,v:3,j:4]) ├── G2: (scan b,cols=(1-4)) │ └── [] │ ├── best: (scan b,cols=(1-4)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── G3: (filters G5) ├── G4: (scan b@v,cols=(1,3),constrained) │ └── [] @@ -740,12 +740,12 @@ memo (optimized, ~8KB, required=[presentation: k:1,u:2,v:3,j:4]) ├── G2: (scan b,cols=(1-4)) │ └── [] │ ├── best: (scan b,cols=(1-4)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── G3: (filters G7 G8) ├── G4: (scan b,cols=(1-4),constrained) │ └── [] │ ├── best: (scan b,cols=(1-4),constrained) - │ └── cost: 364.01 + │ └── cost: 374.81 ├── G5: (filters G7) ├── G6: (select G9 G10) │ └── [] @@ -838,7 +838,7 @@ memo (optimized, ~7KB, required=[presentation: k:1,u:2,v:3,j:4]) ├── G2: (scan b,cols=(1-4)) │ └── [] │ ├── best: (scan b,cols=(1-4)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── G3: (filters G6 G7) ├── G4: (index-join G8 b,cols=(1-4)) │ └── [] @@ -902,12 +902,12 @@ memo (optimized, ~9KB, required=[presentation: k:1,u:2,v:3,j:4]) ├── G2: (scan b,cols=(1-4)) │ └── [] │ ├── best: (scan b,cols=(1-4)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── G3: (filters G8 G9 G10) ├── G4: (scan b,cols=(1-4),constrained) │ └── [] │ ├── best: (scan b,cols=(1-4),constrained) - │ └── cost: 364.01 + │ └── cost: 374.81 ├── G5: (filters G8 G9) ├── G6: (index-join G11 b,cols=(1-4)) │ └── [] @@ -966,22 +966,22 @@ memo (optimized, ~7KB, required=[presentation: k:1,u:2,v:3,j:4]) ├── G1: (select G2 G3) (select G4 G3) │ └── [presentation: k:1,u:2,v:3,j:4] │ ├── best: (select G4 G3) - │ └── cost: 573.65 + │ └── cost: 584.05 ├── G2: (scan b,cols=(1-4)) │ └── [] │ ├── best: (scan b,cols=(1-4)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── G3: (filters G5 G6) ├── G4: (index-join G7 b,cols=(1-4)) │ └── [] │ ├── best: (index-join G7 b,cols=(1-4)) - │ └── cost: 572.82 + │ └── cost: 583.22 ├── G5: (gt G8 G9) ├── G6: (lt G8 G10) ├── G7: (scan b@u,cols=(1,2),constrained) │ └── [] │ ├── best: (scan b@u,cols=(1,2),constrained) - │ └── cost: 87.21 + │ └── cost: 97.61 ├── G8: (tuple G11) ├── G9: (tuple G12) ├── G10: (tuple G13) @@ -1124,25 +1124,25 @@ memo (optimized, ~6KB, required=[presentation: s:4,i:2,f:3] [ordering: +2 opt(4) ├── G1: (select G2 G3) (scan kifs@s_idx,cols=(2-4),constrained) (index-join G4 kifs,cols=(2-4)) │ ├── [presentation: s:4,i:2,f:3] [ordering: +2 opt(4)] │ │ ├── best: (sort G1) - │ │ └── cost: 15.88 + │ │ └── cost: 26.58 │ └── [] │ ├── best: (scan kifs@s_idx,cols=(2-4),constrained) - │ └── cost: 14.71 + │ └── cost: 25.41 ├── G2: (scan kifs,cols=(2-4)) (scan kifs@s_idx,cols=(2-4)) │ ├── [ordering: +2 opt(4)] │ │ ├── best: (sort G2) - │ │ └── cost: 1334.04 + │ │ └── cost: 1344.74 │ └── [] │ ├── best: (scan kifs@s_idx,cols=(2-4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G3: (filters G5) ├── G4: (scan kifs@si_idx,cols=(1,2,4),constrained) │ ├── [ordering: +2 opt(4)] │ │ ├── best: (scan kifs@si_idx,rev,cols=(1,2,4),constrained) - │ │ └── cost: 15.04 + │ │ └── cost: 26.07 │ └── [] │ ├── best: (scan kifs@si_idx,cols=(1,2,4),constrained) - │ └── cost: 14.71 + │ └── cost: 25.41 ├── G5: (eq G6 G7) ├── G6: (variable s) └── G7: (const 'foo') @@ -1154,21 +1154,21 @@ memo (optimized, ~7KB, required=[presentation: j:5]) ├── G1: (project G2 G3 j) │ └── [presentation: j:5] │ ├── best: (project G2 G3 j) - │ └── cost: 14.72 + │ └── cost: 25.32 ├── G2: (select G4 G5) (index-join G6 kifs,cols=(4,5)) (scan kifs@si_idx,cols=(4,5),constrained) │ └── [] │ ├── best: (scan kifs@si_idx,cols=(4,5),constrained) - │ └── cost: 14.61 + │ └── cost: 25.21 ├── G3: (projections) ├── G4: (scan kifs,cols=(4,5)) (scan kifs@si_idx,cols=(4,5)) │ └── [] │ ├── best: (scan kifs@si_idx,cols=(4,5)) - │ └── cost: 1074.61 + │ └── cost: 1085.21 ├── G5: (filters G7) ├── G6: (scan kifs@s_idx,cols=(1,4),constrained) │ └── [] │ ├── best: (scan kifs@s_idx,cols=(1,4),constrained) - │ └── cost: 14.61 + │ └── cost: 25.21 ├── G7: (eq G8 G9) ├── G8: (variable s) └── G9: (const 'foo') @@ -1180,16 +1180,16 @@ memo (optimized, ~6KB, required=[presentation: i:2,k:1]) ├── G1: (project G2 G3 k i) │ └── [presentation: i:2,k:1] │ ├── best: (project G2 G3 k i) - │ └── cost: 364.02 + │ └── cost: 374.72 ├── G2: (select G4 G5) (scan kifs@s_idx,cols=(1,2,4),constrained) (scan kifs@si_idx,cols=(1,2,4),constrained) │ └── [] │ ├── best: (scan kifs@s_idx,cols=(1,2,4),constrained) - │ └── cost: 360.68 + │ └── cost: 371.38 ├── G3: (projections) ├── G4: (scan kifs,cols=(1,2,4)) (scan kifs@s_idx,cols=(1,2,4)) (scan kifs@si_idx,cols=(1,2,4)) │ └── [] │ ├── best: (scan kifs@s_idx,cols=(1,2,4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G5: (filters G6) ├── G6: (ge G7 G8) ├── G7: (variable s) @@ -1588,48 +1588,48 @@ memo (optimized, ~18KB, required=[presentation: i:1]) ├── G1: (project G2 G3 i) (project G4 G3 i) (project G5 G3 i) │ └── [presentation: i:1] │ ├── best: (project G5 G3 i) - │ └── cost: 4.98 + │ └── cost: 15.38 ├── G2: (select G6 G7) (select G8 G9) (index-join G4 p,cols=(1,3)) (select G10 G9) (index-join G5 p,cols=(1,3)) │ └── [] │ ├── best: (index-join G5 p,cols=(1,3)) - │ └── cost: 10.50 + │ └── cost: 20.90 ├── G3: (projections) ├── G4: (select G11 G9) │ └── [] │ ├── best: (select G11 G9) - │ └── cost: 14.53 + │ └── cost: 24.93 ├── G5: (scan p@idx2,partial,cols=(1,5),constrained) │ └── [] │ ├── best: (scan p@idx2,partial,cols=(1,5),constrained) - │ └── cost: 4.96 + │ └── cost: 15.36 ├── G6: (scan p,cols=(1,3)) │ └── [] │ ├── best: (scan p,cols=(1,3)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G7: (filters G12 G13) ├── G8: (index-join G14 p,cols=(1,3)) │ └── [] │ ├── best: (index-join G14 p,cols=(1,3)) - │ └── cost: 374.63 + │ └── cost: 385.03 ├── G9: (filters G12) ├── G10: (index-join G15 p,cols=(1,3)) │ └── [] │ ├── best: (index-join G15 p,cols=(1,3)) - │ └── cost: 70.38 + │ └── cost: 80.78 ├── G11: (scan p@idx2,partial,cols=(1,5)) │ └── [] │ ├── best: (scan p@idx2,partial,cols=(1,5)) - │ └── cost: 14.41 + │ └── cost: 24.81 ├── G12: (eq G16 G17) ├── G13: (eq G18 G19) ├── G14: (select G20 G21) │ └── [] │ ├── best: (select G20 G21) - │ └── cost: 354.03 + │ └── cost: 364.43 ├── G15: (scan p@idx,partial,cols=(3,5),constrained) │ └── [] │ ├── best: (scan p@idx,partial,cols=(3,5),constrained) - │ └── cost: 13.72 + │ └── cost: 24.12 ├── G16: (variable i) ├── G17: (const 3) ├── G18: (variable s) @@ -1637,7 +1637,7 @@ memo (optimized, ~18KB, required=[presentation: i:1]) ├── G20: (scan p@idx,partial,cols=(3,5)) │ └── [] │ ├── best: (scan p@idx,partial,cols=(3,5)) - │ └── cost: 350.68 + │ └── cost: 361.08 └── G21: (filters G13) exec-ddl @@ -1661,16 +1661,16 @@ memo (optimized, ~7KB, required=[presentation: i:1]) ├── G1: (project G2 G3 i) │ └── [presentation: i:1] │ ├── best: (project G2 G3 i) - │ └── cost: 1094.76 + │ └── cost: 1105.46 ├── G2: (select G4 G5) │ └── [] │ ├── best: (select G4 G5) - │ └── cost: 1094.74 + │ └── cost: 1105.44 ├── G3: (projections) ├── G4: (scan p,cols=(1,3)) │ └── [] │ ├── best: (scan p,cols=(1,3)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G5: (filters G6 G7) ├── G6: (eq G8 G9) ├── G7: (eq G10 G11) @@ -1894,20 +1894,20 @@ memo (optimized, ~7KB, required=[presentation: k:1]) ├── G1: (project G2 G3 k) (project G4 G3 k) │ └── [presentation: k:1] │ ├── best: (project G4 G3 k) - │ └── cost: 119.56 + │ └── cost: 129.86 ├── G2: (select G5 G6) (index-join G4 b,cols=(1,4)) │ └── [] │ ├── best: (index-join G4 b,cols=(1,4)) - │ └── cost: 789.51 + │ └── cost: 799.81 ├── G3: (projections) ├── G4: (scan b@j_inv_idx,cols=(1),constrained inverted) │ └── [] │ ├── best: (scan b@j_inv_idx,cols=(1),constrained inverted) - │ └── cost: 118.45 + │ └── cost: 128.75 ├── G5: (scan b,cols=(1,4)) │ └── [] │ ├── best: (scan b,cols=(1,4)) - │ └── cost: 1074.61 + │ └── cost: 1085.21 ├── G6: (filters G7) ├── G7: (contains G8 G9) ├── G8: (variable j) @@ -3521,27 +3521,27 @@ memo (optimized, ~11KB, required=[presentation: k:1,s:2,j:3]) ├── G1: (select G2 G3) (select G4 G5) (index-join G6 pi,cols=(1-3)) │ └── [presentation: k:1,s:2,j:3] │ ├── best: (index-join G6 pi,cols=(1-3)) - │ └── cost: 11.87 + │ └── cost: 22.17 ├── G2: (scan pi,cols=(1-3)) │ └── [] │ ├── best: (scan pi,cols=(1-3)) - │ └── cost: 1074.61 + │ └── cost: 1085.21 ├── G3: (filters G7 G8) ├── G4: (index-join G9 pi,cols=(1-3)) │ └── [] │ ├── best: (index-join G9 pi,cols=(1-3)) - │ └── cost: 19.78 + │ └── cost: 30.08 ├── G5: (filters G8) ├── G6: (scan pi@idx2,partial,cols=(1),constrained inverted) │ └── [] │ ├── best: (scan pi@idx2,partial,cols=(1),constrained inverted) - │ └── cost: 5.15 + │ └── cost: 15.45 ├── G7: (contains G10 G11) ├── G8: (eq G12 G13) ├── G9: (scan pi@idx,partial,cols=(1),constrained inverted) │ └── [] │ ├── best: (scan pi@idx,partial,cols=(1),constrained inverted) - │ └── cost: 6.30 + │ └── cost: 16.60 ├── G10: (variable j) ├── G11: (const '{"a": "b"}') ├── G12: (variable s) @@ -3569,11 +3569,11 @@ memo (optimized, ~7KB, required=[presentation: k:1,s:2,j:3]) ├── G1: (select G2 G3) │ └── [presentation: k:1,s:2,j:3] │ ├── best: (select G2 G3) - │ └── cost: 1084.64 + │ └── cost: 1095.24 ├── G2: (scan pi,cols=(1-3)) │ └── [] │ ├── best: (scan pi,cols=(1-3)) - │ └── cost: 1074.61 + │ └── cost: 1085.21 ├── G3: (filters G4 G5) ├── G4: (contains G6 G7) ├── G5: (eq G8 G9) @@ -4280,6 +4280,25 @@ CREATE TABLE pqr ) ---- +exec-ddl +ALTER TABLE pqr INJECT STATISTICS '[ + { + "columns": ["r"], + "distinct_count": 100, + "null_count": 0, + "row_count": 10000, + "created_at": "2018-01-01 1:00:00.00000+00:00" + }, + { + "columns": ["s"], + "distinct_count": 10, + "null_count": 0, + "row_count": 10000, + "created_at": "2018-01-01 1:00:00.00000+00:00" + } +]' +---- + exec-ddl CREATE TABLE zz ( a INT8 PRIMARY KEY, @@ -4335,40 +4354,40 @@ memo (optimized, ~13KB, required=[presentation: q:2,r:3]) ├── G1: (select G2 G3) (select G4 G5) (select G6 G7) (select G8 G7) (zigzag-join G3 pqr@q pqr@r) │ └── [presentation: q:2,r:3] │ ├── best: (zigzag-join G3 pqr@q pqr@r) - │ └── cost: 1.93 + │ └── cost: 22.83 ├── G2: (scan pqr,cols=(2,3)) │ └── [] │ ├── best: (scan pqr,cols=(2,3)) - │ └── cost: 1084.71 + │ └── cost: 10725.41 ├── G3: (filters G9 G10) ├── G4: (index-join G11 pqr,cols=(2,3)) │ └── [] │ ├── best: (index-join G11 pqr,cols=(2,3)) - │ └── cost: 75.12 + │ └── cost: 84.88 ├── G5: (filters G10) ├── G6: (index-join G12 pqr,cols=(2,3)) │ └── [] │ ├── best: (index-join G12 pqr,cols=(2,3)) - │ └── cost: 75.12 + │ └── cost: 725.42 ├── G7: (filters G9) ├── G8: (index-join G13 pqr,cols=(2,3)) │ └── [] │ ├── best: (index-join G13 pqr,cols=(2,3)) - │ └── cost: 75.22 + │ └── cost: 726.52 ├── G9: (eq G14 G15) ├── G10: (eq G16 G17) ├── G11: (scan pqr@q,cols=(1,2),constrained) │ └── [] │ ├── best: (scan pqr@q,cols=(1,2),constrained) - │ └── cost: 14.41 + │ └── cost: 24.72 ├── G12: (scan pqr@r,cols=(1,3),constrained) │ └── [] │ ├── best: (scan pqr@r,cols=(1,3),constrained) - │ └── cost: 14.41 + │ └── cost: 118.41 ├── G13: (scan pqr@rs,cols=(1,3),constrained) │ └── [] │ ├── best: (scan pqr@rs,cols=(1,3),constrained) - │ └── cost: 14.51 + │ └── cost: 119.51 ├── G14: (variable q) ├── G15: (const 1) ├── G16: (variable r) @@ -4416,45 +4435,45 @@ memo (optimized, ~15KB, required=[presentation: q:2,r:3,s:4]) ├── G1: (select G2 G3) (select G4 G5) (select G6 G7) (select G8 G7) (lookup-join G9 G10 pqr,keyCols=[1],outCols=(2-4)) │ └── [presentation: q:2,r:3,s:4] │ ├── best: (lookup-join G9 G10 pqr,keyCols=[1],outCols=(2-4)) - │ └── cost: 7.48 + │ └── cost: 28.47 ├── G2: (scan pqr,cols=(2-4)) │ └── [] │ ├── best: (scan pqr,cols=(2-4)) - │ └── cost: 1094.81 + │ └── cost: 10825.61 ├── G3: (filters G11 G12) ├── G4: (index-join G13 pqr,cols=(2-4)) │ └── [] │ ├── best: (index-join G13 pqr,cols=(2-4)) - │ └── cost: 75.22 + │ └── cost: 84.98 ├── G5: (filters G12) ├── G6: (index-join G14 pqr,cols=(2-4)) │ └── [] │ ├── best: (index-join G14 pqr,cols=(2-4)) - │ └── cost: 75.22 + │ └── cost: 726.42 ├── G7: (filters G11) ├── G8: (index-join G15 pqr,cols=(2-4)) │ └── [] │ ├── best: (index-join G15 pqr,cols=(2-4)) - │ └── cost: 75.32 + │ └── cost: 727.62 ├── G9: (zigzag-join G3 pqr@q pqr@r) │ └── [] │ ├── best: (zigzag-join G3 pqr@q pqr@r) - │ └── cost: 1.94 + │ └── cost: 22.94 ├── G10: (filters) ├── G11: (eq G16 G17) ├── G12: (eq G18 G19) ├── G13: (scan pqr@q,cols=(1,2),constrained) │ └── [] │ ├── best: (scan pqr@q,cols=(1,2),constrained) - │ └── cost: 14.41 + │ └── cost: 24.72 ├── G14: (scan pqr@r,cols=(1,3),constrained) │ └── [] │ ├── best: (scan pqr@r,cols=(1,3),constrained) - │ └── cost: 14.41 + │ └── cost: 118.41 ├── G15: (scan pqr@rs,cols=(1,3,4),constrained) │ └── [] │ ├── best: (scan pqr@rs,cols=(1,3,4),constrained) - │ └── cost: 14.61 + │ └── cost: 120.61 ├── G16: (variable q) ├── G17: (const 1) ├── G18: (variable r) @@ -4481,32 +4500,32 @@ memo (optimized, ~11KB, required=[presentation: q:2,s:4]) ├── G1: (select G2 G3) (select G4 G5) (select G6 G7) (zigzag-join G3 pqr@q pqr@s) │ └── [presentation: q:2,s:4] │ ├── best: (zigzag-join G3 pqr@q pqr@s) - │ └── cost: 1.94 + │ └── cost: 23.13 ├── G2: (scan pqr,cols=(2,4)) │ └── [] │ ├── best: (scan pqr,cols=(2,4)) - │ └── cost: 1084.71 + │ └── cost: 10725.41 ├── G3: (filters G8 G9) ├── G4: (index-join G10 pqr,cols=(2,4)) │ └── [] │ ├── best: (index-join G10 pqr,cols=(2,4)) - │ └── cost: 75.12 + │ └── cost: 84.88 ├── G5: (filters G9) ├── G6: (index-join G11 pqr,cols=(2,4)) │ └── [] │ ├── best: (index-join G11 pqr,cols=(2,4)) - │ └── cost: 75.22 + │ └── cost: 7134.52 ├── G7: (filters G8) ├── G8: (eq G12 G13) ├── G9: (eq G14 G15) ├── G10: (scan pqr@q,cols=(1,2),constrained) │ └── [] │ ├── best: (scan pqr@q,cols=(1,2),constrained) - │ └── cost: 14.41 + │ └── cost: 24.72 ├── G11: (scan pqr@s,cols=(1,4),constrained) │ └── [] │ ├── best: (scan pqr@s,cols=(1,4),constrained) - │ └── cost: 14.51 + │ └── cost: 1064.51 ├── G12: (variable q) ├── G13: (const 1) ├── G14: (variable s) @@ -4535,40 +4554,40 @@ memo (optimized, ~13KB, required=[presentation: r:3,t:5]) ├── G1: (select G2 G3) (select G4 G5) (select G6 G5) (select G7 G8) (zigzag-join G3 pqr@rs pqr@ts) │ └── [presentation: r:3,t:5] │ ├── best: (zigzag-join G3 pqr@rs pqr@ts) - │ └── cost: 1.95 + │ └── cost: 23.05 ├── G2: (scan pqr,cols=(3,5)) │ └── [] │ ├── best: (scan pqr,cols=(3,5)) - │ └── cost: 1084.71 + │ └── cost: 10725.41 ├── G3: (filters G9 G10) ├── G4: (index-join G11 pqr,cols=(3,5)) │ └── [] │ ├── best: (index-join G11 pqr,cols=(3,5)) - │ └── cost: 75.12 + │ └── cost: 725.42 ├── G5: (filters G10) ├── G6: (index-join G12 pqr,cols=(3,5)) │ └── [] │ ├── best: (index-join G12 pqr,cols=(3,5)) - │ └── cost: 75.22 + │ └── cost: 726.52 ├── G7: (index-join G13 pqr,cols=(3,5)) │ └── [] │ ├── best: (index-join G13 pqr,cols=(3,5)) - │ └── cost: 75.22 + │ └── cost: 85.08 ├── G8: (filters G9) ├── G9: (eq G14 G15) ├── G10: (eq G16 G17) ├── G11: (scan pqr@r,cols=(1,3),constrained) │ └── [] │ ├── best: (scan pqr@r,cols=(1,3),constrained) - │ └── cost: 14.41 + │ └── cost: 118.41 ├── G12: (scan pqr@rs,cols=(1,3),constrained) │ └── [] │ ├── best: (scan pqr@rs,cols=(1,3),constrained) - │ └── cost: 14.51 + │ └── cost: 119.51 ├── G13: (scan pqr@ts,cols=(1,5),constrained) │ └── [] │ ├── best: (scan pqr@ts,cols=(1,5),constrained) - │ └── cost: 14.51 + │ └── cost: 24.92 ├── G14: (variable r) ├── G15: (const 1) ├── G16: (variable t) @@ -4937,59 +4956,59 @@ memo (optimized, ~31KB, required=[presentation: p:1,q:2,r:3,s:4]) ├── G1: (select G2 G3) (select G4 G5) (select G6 G7) (select G8 G9) (select G10 G9) (lookup-join G11 G12 pqr,keyCols=[1],outCols=(1-4)) (zigzag-join G3 pqr@q pqr@s) (zigzag-join G3 pqr@q pqr@rs) (lookup-join G13 G9 pqr,keyCols=[1],outCols=(1-4)) │ └── [presentation: p:1,q:2,r:3,s:4] │ ├── best: (zigzag-join G3 pqr@q pqr@s) - │ └── cost: 1.95 + │ └── cost: 23.15 ├── G2: (scan pqr,cols=(1-4)) │ └── [] │ ├── best: (scan pqr,cols=(1-4)) - │ └── cost: 1104.91 + │ └── cost: 10925.81 ├── G3: (filters G14 G15 G16) ├── G4: (index-join G17 pqr,cols=(1-4)) │ └── [] │ ├── best: (index-join G17 pqr,cols=(1-4)) - │ └── cost: 75.22 + │ └── cost: 84.98 ├── G5: (filters G15 G16) ├── G6: (index-join G18 pqr,cols=(1-4)) │ └── [] │ ├── best: (index-join G18 pqr,cols=(1-4)) - │ └── cost: 75.22 + │ └── cost: 726.42 ├── G7: (filters G14 G16) ├── G8: (index-join G19 pqr,cols=(1-4)) │ └── [] │ ├── best: (index-join G19 pqr,cols=(1-4)) - │ └── cost: 21.76 + │ └── cost: 1145.34 ├── G9: (filters G14) ├── G10: (index-join G20 pqr,cols=(1-4)) │ └── [] │ ├── best: (index-join G20 pqr,cols=(1-4)) - │ └── cost: 10.51 + │ └── cost: 85.92 ├── G11: (zigzag-join G21 pqr@q pqr@r) │ └── [] │ ├── best: (zigzag-join G21 pqr@q pqr@r) - │ └── cost: 1.94 + │ └── cost: 22.94 ├── G12: (filters G16) ├── G13: (zigzag-join G5 pqr@r pqr@s) │ └── [] │ ├── best: (zigzag-join G5 pqr@r pqr@s) - │ └── cost: 1.95 + │ └── cost: 42.23 ├── G14: (eq G22 G23) ├── G15: (eq G24 G23) ├── G16: (eq G25 G26) ├── G17: (scan pqr@q,cols=(1,2),constrained) │ └── [] │ ├── best: (scan pqr@q,cols=(1,2),constrained) - │ └── cost: 14.41 + │ └── cost: 24.72 ├── G18: (scan pqr@r,cols=(1,3),constrained) │ └── [] │ ├── best: (scan pqr@r,cols=(1,3),constrained) - │ └── cost: 14.41 + │ └── cost: 118.41 ├── G19: (select G27 G28) │ └── [] │ ├── best: (select G27 G28) - │ └── cost: 14.73 + │ └── cost: 1084.63 ├── G20: (scan pqr@rs,cols=(1,3,4),constrained) │ └── [] │ ├── best: (scan pqr@rs,cols=(1,3,4),constrained) - │ └── cost: 4.98 + │ └── cost: 25.21 ├── G21: (filters G14 G15) ├── G22: (variable q) ├── G23: (const 1) @@ -4999,7 +5018,7 @@ memo (optimized, ~31KB, required=[presentation: p:1,q:2,r:3,s:4]) ├── G27: (scan pqr@s,cols=(1,3,4),constrained) │ └── [] │ ├── best: (scan pqr@s,cols=(1,3,4),constrained) - │ └── cost: 14.61 + │ └── cost: 1074.61 └── G28: (filters G15) # Zigzag joins cannot be planned for indexes where equality columns do not @@ -5029,32 +5048,32 @@ memo (optimized, ~9KB, required=[presentation: q:2,t:5]) ├── G1: (select G2 G3) (select G4 G5) (select G6 G7) │ └── [presentation: q:2,t:5] │ ├── best: (select G4 G5) - │ └── cost: 75.24 + │ └── cost: 85.00 ├── G2: (scan pqr,cols=(2,5)) │ └── [] │ ├── best: (scan pqr,cols=(2,5)) - │ └── cost: 1084.71 + │ └── cost: 10725.41 ├── G3: (filters G8 G9) ├── G4: (index-join G10 pqr,cols=(2,5)) │ └── [] │ ├── best: (index-join G10 pqr,cols=(2,5)) - │ └── cost: 75.12 + │ └── cost: 84.88 ├── G5: (filters G9) ├── G6: (index-join G11 pqr,cols=(2,5)) │ └── [] │ ├── best: (index-join G11 pqr,cols=(2,5)) - │ └── cost: 75.22 + │ └── cost: 85.08 ├── G7: (filters G8) ├── G8: (eq G12 G13) ├── G9: (eq G14 G15) ├── G10: (scan pqr@q,cols=(1,2),constrained) │ └── [] │ ├── best: (scan pqr@q,cols=(1,2),constrained) - │ └── cost: 14.41 + │ └── cost: 24.72 ├── G11: (scan pqr@ts,cols=(1,5),constrained) │ └── [] │ ├── best: (scan pqr@ts,cols=(1,5),constrained) - │ └── cost: 14.51 + │ └── cost: 24.92 ├── G12: (variable q) ├── G13: (const 1) ├── G14: (variable t) @@ -5068,16 +5087,16 @@ memo (optimized, ~6KB, required=[presentation: c:3]) ├── G1: (project G2 G3 c) │ └── [presentation: c:3] │ ├── best: (project G2 G3 c) - │ └── cost: 14.62 + │ └── cost: 25.12 ├── G2: (select G4 G5) (scan zz_redundant@idx_u,cols=(2,3),constrained) (scan zz_redundant@idx_v,cols=(2,3),constrained) │ └── [] │ ├── best: (scan zz_redundant@idx_u,cols=(2,3),constrained) - │ └── cost: 14.51 + │ └── cost: 25.01 ├── G3: (projections) ├── G4: (scan zz_redundant,cols=(2,3)) (scan zz_redundant@idx_u,cols=(2,3)) (scan zz_redundant@idx_v,cols=(2,3)) │ └── [] │ ├── best: (scan zz_redundant,cols=(2,3)) - │ └── cost: 1064.51 + │ └── cost: 1075.01 ├── G5: (filters G6) ├── G6: (eq G7 G8) ├── G7: (variable b) @@ -6469,30 +6488,30 @@ memo (optimized, ~18KB, required=[presentation: k:1,a:2,b:3,c:4]) ├── G1: (select G2 G3) (index-join G4 t58390,cols=(1-4)) (distinct-on G5 G6 cols=(1)) │ └── [presentation: k:1,a:2,b:3,c:4] │ ├── best: (select G2 G3) - │ └── cost: 1104.83 + │ └── cost: 1115.63 ├── G2: (scan t58390,cols=(1-4)) │ └── [] │ ├── best: (scan t58390,cols=(1-4)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── G3: (filters G7) ├── G4: (scan t58390@secondary,partial,cols=(1,4)) │ └── [] │ ├── best: (scan t58390@secondary,partial,cols=(1,4)) - │ └── cost: 350.68 + │ └── cost: 361.08 ├── G5: (union-all G8 G9) │ └── [] │ ├── best: (union-all G8 G9) - │ └── cost: 2216.34 + │ └── cost: 2237.94 ├── G6: (aggregations G10 G11 G12) ├── G7: (or G13 G14) ├── G8: (select G15 G16) (select G17 G16) │ └── [] │ ├── best: (select G15 G16) - │ └── cost: 1104.83 + │ └── cost: 1115.63 ├── G9: (select G18 G19) (select G20 G19) │ └── [] │ ├── best: (select G18 G19) - │ └── cost: 1104.83 + │ └── cost: 1115.63 ├── G10: (const-agg G21) ├── G11: (const-agg G22) ├── G12: (const-agg G23) @@ -6501,21 +6520,21 @@ memo (optimized, ~18KB, required=[presentation: k:1,a:2,b:3,c:4]) ├── G15: (scan t58390,cols=(6-9)) │ └── [] │ ├── best: (scan t58390,cols=(6-9)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── G16: (filters G25) ├── G17: (index-join G26 t58390,cols=(6-9)) │ └── [] │ ├── best: (index-join G26 t58390,cols=(6-9)) - │ └── cost: 2374.02 + │ └── cost: 2384.42 ├── G18: (scan t58390,cols=(11-14)) │ └── [] │ ├── best: (scan t58390,cols=(11-14)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── G19: (filters G27) ├── G20: (index-join G28 t58390,cols=(11-14)) │ └── [] │ ├── best: (index-join G28 t58390,cols=(11-14)) - │ └── cost: 2374.02 + │ └── cost: 2384.42 ├── G21: (variable a) ├── G22: (variable b) ├── G23: (variable c) @@ -6524,12 +6543,12 @@ memo (optimized, ~18KB, required=[presentation: k:1,a:2,b:3,c:4]) ├── G26: (scan t58390@secondary,partial,cols=(6,9)) │ └── [] │ ├── best: (scan t58390@secondary,partial,cols=(6,9)) - │ └── cost: 350.68 + │ └── cost: 361.08 ├── G27: (gt G30 G24) ├── G28: (scan t58390@secondary,partial,cols=(11,14)) │ └── [] │ ├── best: (scan t58390@secondary,partial,cols=(11,14)) - │ └── cost: 350.68 + │ └── cost: 361.08 ├── G29: (variable a) └── G30: (variable b) @@ -6557,51 +6576,51 @@ memo (optimized, ~28KB, required=[presentation: a:1] [ordering: +2]) ├── G1: (project G2 G3 a b) │ ├── [presentation: a:1] [ordering: +2] │ │ ├── best: (sort G1) - │ │ └── cost: 1084.68 + │ │ └── cost: 1095.28 │ └── [] │ ├── best: (project G2 G3 a b) - │ └── cost: 1084.65 + │ └── cost: 1095.25 ├── G2: (select G4 G5) (select G6 G7) (distinct-on G8 G9 cols=(1)) │ ├── [ordering: +(2|3)] │ │ ├── best: (sort G2) - │ │ └── cost: 1084.67 + │ │ └── cost: 1095.27 │ └── [] │ ├── best: (select G4 G5) - │ └── cost: 1084.64 + │ └── cost: 1095.24 ├── G3: (projections) ├── G4: (scan t61795 [as=t1],cols=(1-3)) │ ├── [ordering: +2] │ │ ├── best: (sort G4) - │ │ └── cost: 1323.94 + │ │ └── cost: 1334.54 │ └── [] │ ├── best: (scan t61795 [as=t1],cols=(1-3)) - │ └── cost: 1074.61 + │ └── cost: 1085.21 ├── G5: (filters G10 G11) ├── G6: (index-join G12 t61795,cols=(1-3)) │ ├── [ordering: +2] │ │ ├── best: (index-join G12="[ordering: +2]" t61795,cols=(1-3)) - │ │ └── cost: 3040.04 + │ │ └── cost: 3050.44 │ └── [] │ ├── best: (index-join G12 t61795,cols=(1-3)) - │ └── cost: 3040.04 + │ └── cost: 3050.44 ├── G7: (filters G10) ├── G8: (union-all G13 G14) │ ├── [ordering: +(2|3)] │ │ ├── best: (sort G8) - │ │ └── cost: 1089.85 + │ │ └── cost: 1100.45 │ └── [] │ ├── best: (union-all G13 G14) - │ └── cost: 1089.76 + │ └── cost: 1100.36 ├── G9: (aggregations G15 G16) ├── G10: (eq G17 G18) ├── G11: (or G19 G20) ├── G12: (select G21 G22) │ ├── [ordering: +2] │ │ ├── best: (select G21="[ordering: +2]" G22) - │ │ └── cost: 1043.53 + │ │ └── cost: 1053.93 │ └── [] │ ├── best: (select G21 G22) - │ └── cost: 1043.53 + │ └── cost: 1053.93 ├── G13: (select G23 G24) (select G25 G26) (select G27 G26) │ └── [] │ ├── best: (select G25 G26) @@ -6609,7 +6628,7 @@ memo (optimized, ~28KB, required=[presentation: a:1] [ordering: +2]) ├── G14: (select G28 G29) (select G30 G31) │ └── [] │ ├── best: (select G28 G29) - │ └── cost: 1084.64 + │ └── cost: 1095.24 ├── G15: (const-agg G18) ├── G16: (const-agg G17) ├── G17: (variable t1.c) @@ -6619,15 +6638,15 @@ memo (optimized, ~28KB, required=[presentation: a:1] [ordering: +2]) ├── G21: (scan t61795@secondary [as=t1],cols=(1,2),constrained) │ ├── [ordering: +2] │ │ ├── best: (scan t61795@secondary [as=t1],cols=(1,2),constrained) - │ │ └── cost: 1033.61 + │ │ └── cost: 1044.01 │ └── [] │ ├── best: (scan t61795@secondary [as=t1],cols=(1,2),constrained) - │ └── cost: 1033.61 + │ └── cost: 1044.01 ├── G22: (filters G11) ├── G23: (scan t61795 [as=t1],cols=(9-11)) │ └── [] │ ├── best: (scan t61795 [as=t1],cols=(9-11)) - │ └── cost: 1074.61 + │ └── cost: 1085.21 ├── G24: (filters G35 G36) ├── G25: (scan t61795 [as=t1],cols=(9-11),constrained) │ └── [] @@ -6637,16 +6656,16 @@ memo (optimized, ~28KB, required=[presentation: a:1] [ordering: +2]) ├── G27: (index-join G37 t61795,cols=(9-11)) │ └── [] │ ├── best: (index-join G37 t61795,cols=(9-11)) - │ └── cost: 1049.59 + │ └── cost: 1059.99 ├── G28: (scan t61795 [as=t1],cols=(13-15)) │ └── [] │ ├── best: (scan t61795 [as=t1],cols=(13-15)) - │ └── cost: 1074.61 + │ └── cost: 1085.21 ├── G29: (filters G38 G39) ├── G30: (index-join G40 t61795,cols=(13-15)) │ └── [] │ ├── best: (index-join G40 t61795,cols=(13-15)) - │ └── cost: 3040.04 + │ └── cost: 3050.44 ├── G31: (filters G38) ├── G32: (variable t1.a) ├── G33: (const 10) @@ -6656,13 +6675,13 @@ memo (optimized, ~28KB, required=[presentation: a:1] [ordering: +2]) ├── G37: (select G45 G46) │ └── [] │ ├── best: (select G45 G46) - │ └── cost: 1043.53 + │ └── cost: 1053.93 ├── G38: (eq G47 G48) ├── G39: (ne G48 G49) ├── G40: (select G50 G51) │ └── [] │ ├── best: (select G50 G51) - │ └── cost: 1043.53 + │ └── cost: 1053.93 ├── G41: (scalar-list G18) ├── G42: (variable t1.c) ├── G43: (variable t1.b) @@ -6670,7 +6689,7 @@ memo (optimized, ~28KB, required=[presentation: a:1] [ordering: +2]) ├── G45: (scan t61795@secondary [as=t1],cols=(9,10),constrained) │ └── [] │ ├── best: (scan t61795@secondary [as=t1],cols=(9,10),constrained) - │ └── cost: 1033.61 + │ └── cost: 1044.01 ├── G46: (filters G36) ├── G47: (variable t1.c) ├── G48: (variable t1.b) @@ -6678,7 +6697,7 @@ memo (optimized, ~28KB, required=[presentation: a:1] [ordering: +2]) ├── G50: (scan t61795@secondary [as=t1],cols=(13,14),constrained) │ └── [] │ ├── best: (scan t61795@secondary [as=t1],cols=(13,14),constrained) - │ └── cost: 1033.61 + │ └── cost: 1044.01 ├── G51: (filters G39) └── G52: (scalar-list G48)