From 83e64974a6ef06d27abc49a58f759d6b79238db3 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 | 66 +-- 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/opbench/testdata/hash-set-op.csv | 36 +- .../opt/opbench/testdata/streaming-set-op.csv | 18 +- 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/optgen/exprgen/testdata/set | 14 +- pkg/sql/opt/props/cardinality.go | 5 + .../testutils/opttester/testdata/opt-steps | 58 +-- pkg/sql/opt/xform/coster.go | 44 ++ 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 | 181 ++++++++- 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 | 354 ++++++++-------- pkg/sql/opt/xform/testdata/rules/join | 262 ++++++------ pkg/sql/opt/xform/testdata/rules/join_order | 126 +++--- pkg/sql/opt/xform/testdata/rules/scan | 40 +- pkg/sql/opt/xform/testdata/rules/select | 379 +++++++++--------- pkg/sql/opt/xform/testdata/rules/set | 124 +++--- 44 files changed, 1354 insertions(+), 1117 deletions(-) diff --git a/pkg/sql/logictest/testdata/logic_test/alter_primary_key b/pkg/sql/logictest/testdata/logic_test/alter_primary_key index ede5facb0dc6..b697a2090946 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 fcb74e8fefeb..5aa25583b548 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 bc352a45c425..6daff416a155 100644 --- a/pkg/sql/logictest/testdata/logic_test/vectorize_local +++ b/pkg/sql/logictest/testdata/logic_test/vectorize_local @@ -104,7 +104,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 @@ -112,12 +112,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) @@ -125,14 +125,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 8cd53b149eba..6281e916d193 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/distsql_agg +++ b/pkg/sql/opt/exec/execbuilder/testdata/distsql_agg @@ -963,7 +963,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) @@ -971,7 +971,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 14fcd9103ff9..5961b139c71a 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/explain +++ b/pkg/sql/opt/exec/execbuilder/testdata/explain @@ -1097,21 +1097,21 @@ 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) └── 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) └── scan tc@c ├── 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) @@ -1121,21 +1121,21 @@ 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) └── 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) └── scan tc@c ├── 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) @@ -1183,20 +1183,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.87625 + ├── cost: 2271.67625 ├── 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) @@ -1224,7 +1224,7 @@ sort ├── columns: a:1 b:2 [hidden: column6:6] ├── immutable ├── stats: [rows=333.333333] - ├── cost: 1204.26951 + ├── cost: 1215.26951 ├── fd: (1,2)-->(6) ├── ordering: +6 ├── prune: (1,2,6) @@ -1233,7 +1233,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) @@ -1241,12 +1241,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 @@ -1261,7 +1261,7 @@ sort ├── columns: a:1(int) b:2(int) [hidden: column6:6(int)] ├── immutable ├── stats: [rows=333.333333] - ├── cost: 1204.26951 + ├── cost: 1215.26951 ├── fd: (1,2)-->(6) ├── ordering: +6 ├── prune: (1,2,6) @@ -1270,7 +1270,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) @@ -1278,12 +1278,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 d26f96557541..23ffc70a18bb 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/inverted_index +++ b/pkg/sql/opt/exec/execbuilder/testdata/inverted_index @@ -1468,7 +1468,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) @@ -1477,13 +1477,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) @@ -1558,7 +1558,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) @@ -1568,13 +1568,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) @@ -1594,7 +1594,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) @@ -1604,13 +1604,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) @@ -1631,7 +1631,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) @@ -1641,13 +1641,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 3a2df7417ff0..a886085c933c 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/stats +++ b/pkg/sql/opt/exec/execbuilder/testdata/stats @@ -219,13 +219,13 @@ distinct-on ├── columns: u:1 v:2 ├── grouping columns: u:1 v:2 ├── stats: [rows=20.0617284, distinct(1,2)=20.0617284, null(1,2)=0] - ├── cost: 41.897284 + ├── cost: 52.897284 ├── 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 ├── prune: (2) └── interesting orderings: (+1) (+2) @@ -239,13 +239,13 @@ distinct-on ├── columns: u:1 v:2 ├── grouping columns: u:1 v:2 ├── stats: [rows=33.3333333, distinct(1,2)=33.3333333, null(1,2)=0] - ├── cost: 42.03 + ├── cost: 53.03 ├── 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 ├── prune: (2) └── interesting orderings: (+1) (+2) @@ -259,7 +259,7 @@ distinct-on ├── columns: u:1 v:2 ├── grouping columns: u:1 v:2 ├── stats: [rows=100, distinct(1,2)=100, null(1,2)=0] - ├── cost: 118.030563 + ├── cost: 129.030563 ├── key: (1,2) └── scan uv@uv_u_idx ├── columns: u:1 v:2 @@ -267,7 +267,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 ├── prune: (2) └── interesting orderings: (+1) (+2) @@ -281,7 +281,7 @@ distinct-on ├── columns: u:1 v:2 ├── grouping columns: u:1 v:2 ├── stats: [rows=25, distinct(1,2)=25, null(1,2)=0] - ├── cost: 117.28 + ├── cost: 128.28 ├── key: (1,2) └── scan uv@uv_u_idx ├── columns: u:1 v:2 @@ -289,7 +289,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 ├── prune: (2) └── interesting orderings: (+1) (+2) diff --git a/pkg/sql/opt/memo/testdata/format b/pkg/sql/opt/memo/testdata/format index e6763ec7ba3f..271d6cece013 100644 --- a/pkg/sql/opt/memo/testdata/format +++ b/pkg/sql/opt/memo/testdata/format @@ -9,7 +9,7 @@ project ├── columns: "?column?":7(int) min:6(int!null) [hidden: t.public.t.a:1(int)] ├── immutable ├── stats: [rows=98.1771622] - ├── cost: 1114.43684 + ├── cost: 1125.03684 ├── key: (1) ├── fd: (1)-->(6,7) ├── ordering: +1 @@ -18,7 +18,7 @@ project │ ├── columns: t.public.t.a:1(int) min:6(int!null) │ ├── immutable │ ├── stats: [rows=98.1771622, distinct(1)=98.1771622, null(1)=1] - │ ├── cost: 1112.46329 + │ ├── cost: 1123.06329 │ ├── key: (1) │ ├── fd: (1)-->(6) │ ├── 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.5323 + │ ├── cost: 1106.1323 │ ├── key: (1) │ ├── fd: (1)-->(6) │ ├── prune: (6) @@ -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?":7(int) min:6(int!null) [hidden: t.public.t.a:1(int)] ├── stats: [rows=98.1771622] - ├── cost: 1114.43684 + ├── cost: 1125.03684 ├── ordering: +1 ├── sort │ ├── columns: t.public.t.a:1(int) min:6(int!null) │ ├── stats: [rows=98.1771622, distinct(1)=98.1771622, null(1)=1] - │ ├── cost: 1112.46329 + │ ├── cost: 1123.06329 │ ├── ordering: +1 │ └── group-by │ ├── columns: t.public.t.a:1(int) min:6(int!null) │ ├── grouping columns: t.public.t.a:1(int) │ ├── stats: [rows=98.1771622, distinct(1)=98.1771622, null(1)=1] - │ ├── cost: 1095.5323 + │ ├── cost: 1106.1323 │ ├── 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.43684 + ├── cost: 1125.03684 ├── key: (1) ├── fd: (1)-->(6,7) ├── prune: (1,6,7) ├── sort │ ├── stats: [rows=98.1771622, distinct(1)=98.1771622, null(1)=1] - │ ├── cost: 1112.46329 + │ ├── cost: 1123.06329 │ ├── key: (1) │ ├── fd: (1)-->(6) │ ├── prune: (6) │ └── group-by │ ├── stats: [rows=98.1771622, distinct(1)=98.1771622, null(1)=1] - │ ├── cost: 1095.5323 + │ ├── cost: 1106.1323 │ ├── key: (1) │ ├── fd: (1)-->(6) │ ├── prune: (6) │ ├── 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 13dd4bf7df07..d0e75c64d65d 100644 --- a/pkg/sql/opt/memo/testdata/memo +++ b/pkg/sql/opt/memo/testdata/memo @@ -132,44 +132,44 @@ memo (optimized, ~20KB, required=[presentation: y:2,x:5,c:10] [ordering: +2]) ├── G1: (project G2 G3 y x) │ ├── [presentation: y:2,x:5,c:10] [ordering: +2] │ │ ├── best: (project G2="[ordering: +2]" G3 y x) - │ │ └── cost: 1744.67 + │ │ └── cost: 1755.07 │ └── [] │ ├── best: (project G2 G3 y x) - │ └── cost: 1744.67 + │ └── cost: 1755.07 ├── G2: (limit G4 G5 ordering=+2) │ ├── [ordering: +2] │ │ ├── best: (limit G4="[ordering: +2] [limit hint: 10.00]" G5 ordering=+2) - │ │ └── cost: 1744.46 + │ │ └── cost: 1754.86 │ └── [] │ ├── best: (limit G4="[ordering: +2] [limit hint: 10.00]" G5 ordering=+2) - │ └── cost: 1744.46 + │ └── cost: 1754.86 ├── G3: (projections G6) ├── G4: (inner-join G7 G8 G9) (inner-join G8 G7 G9) (lookup-join G7 G10 b,keyCols=[9],outCols=(2,5,9)) (merge-join G8 G7 G10 inner-join,+5,+9) │ ├── [ordering: +2] [limit hint: 10.00] │ │ ├── best: (lookup-join G7="[ordering: +2] [limit hint: 100.00]" G10 b,keyCols=[9],outCols=(2,5,9)) - │ │ └── cost: 1744.35 + │ │ └── cost: 1754.75 │ └── [] │ ├── best: (inner-join G8 G7 G9) - │ └── cost: 2137.11 + │ └── cost: 2157.81 ├── G5: (const 10) ├── G6: (plus G11 G12) ├── G7: (project G13 G14 y) │ ├── [ordering: +2] [limit hint: 100.00] │ │ ├── best: (sort G7) - │ │ └── cost: 1140.34 + │ │ └── cost: 1150.74 │ ├── [ordering: +9] │ │ ├── best: (sort G7) - │ │ └── cost: 1140.34 + │ │ └── cost: 1150.74 │ └── [] │ ├── best: (project G13 G14 y) - │ └── cost: 1071.11 + │ └── cost: 1081.51 ├── G8: (scan b,cols=(5)) │ ├── [ordering: +5] │ │ ├── best: (scan b,cols=(5)) - │ │ └── cost: 1044.31 + │ │ └── cost: 1054.61 │ └── [] │ ├── best: (scan b,cols=(5)) - │ └── cost: 1044.31 + │ └── cost: 1054.61 ├── G9: (filters G15) ├── G10: (filters) ├── G11: (variable y) @@ -177,19 +177,19 @@ memo (optimized, ~20KB, required=[presentation: y:2,x:5,c:10] [ordering: +2]) ├── G13: (select G16 G17) │ ├── [ordering: +2] [limit hint: 100.00] │ │ ├── best: (sort G13) - │ │ └── cost: 1133.66 + │ │ └── cost: 1144.06 │ └── [] │ ├── 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.88 + │ │ └── cost: 1304.28 │ └── [] │ ├── best: (scan a,cols=(1,2)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G17: (filters G21) ├── G18: (cast G22 STRING) ├── G19: (variable column9) @@ -207,16 +207,16 @@ memo (optimized, ~6KB, required=[presentation: a:5,b:6,c:7,d:8]) ├── G1: (project G2 G3) │ └── [presentation: a:5,b:6,c:7,d:8] │ ├── 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,25 +272,25 @@ memo (optimized, ~7KB, required=[presentation: x:11,y:12]) ├── G1: (union G2 G3) (union G2 G3 ordering=+11,+12) │ └── [presentation: x:11,y:12] │ ├── best: (union G2 G3) - │ └── cost: 2179.45 + │ └── cost: 2200.25 ├── G2: (scan a,cols=(1,2)) │ ├── [ordering: +1] │ │ ├── best: (scan a,cols=(1,2)) - │ │ └── cost: 1054.41 + │ │ └── cost: 1064.81 │ └── [] │ ├── best: (scan a,cols=(1,2)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G3: (project G4 G5) │ ├── [ordering: +9,+10] │ │ ├── best: (sort G3) - │ │ └── cost: 1334.86 + │ │ └── cost: 1345.26 │ └── [] │ ├── best: (project G4 G5) - │ └── cost: 1084.42 + │ └── cost: 1094.82 ├── G4: (scan a,cols=(5,6)) │ └── [] │ ├── best: (scan a,cols=(5,6)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G5: (projections G6 G7) ├── G6: (plus G8 G9) ├── G7: (plus G10 G9) @@ -305,11 +305,11 @@ memo (optimized, ~4KB, required=[presentation: array_agg:5]) ├── G1: (scalar-group-by G2 G3 cols=()) │ └── [presentation: array_agg:5] │ ├── 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) @@ -321,16 +321,16 @@ memo (optimized, ~4KB, required=[presentation: array_agg:5]) ├── G1: (project G2 G3 array_agg) │ └── [presentation: array_agg:5] │ ├── 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) @@ -342,14 +342,14 @@ memo (optimized, ~3KB, required=[presentation: array_agg:5]) ├── G1: (scalar-group-by G2 G3 cols=(),ordering=+2) │ └── [presentation: array_agg:5] │ ├── best: (scalar-group-by G2="[ordering: +2]" G3 cols=(),ordering=+2) - │ └── cost: 1303.91 + │ └── cost: 1314.31 ├── G2: (scan a,cols=(1,2)) │ ├── [ordering: +2] │ │ ├── best: (sort G2) - │ │ └── cost: 1293.88 + │ │ └── cost: 1304.28 │ └── [] │ ├── 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 a8d5306494a1..1e44935f8aae 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.91 + │ └── cost: 2653.41 ├── G2: (limit G4 G5 ordering=+1) │ └── [] │ ├── best: (limit G4="[ordering: +1] [limit hint: 1.00]" G5 ordering=+1) - │ └── cost: 2642.89 + │ └── cost: 2653.39 ├── 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.87 + │ │ └── cost: 2653.37 │ └── [] │ ├── 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.76 + │ │ └── cost: 2644.26 │ └── [] │ ├── 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: 22156.46 + │ │ └── cost: 22166.86 │ └── [] │ ├── 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,6),constrained inverted) │ └── [] │ ├── best: (scan t@secondary,cols=(3,6),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.76 + │ │ └── cost: 2644.26 │ └── [] │ ├── 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,6),constrained inverted) │ └── [] │ ├── best: (scan t@secondary,cols=(3,6),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 1e0c5b964ad2..9824283c88c2 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:6(int!null) t.public.def.e:7(int!null) t.public.def.f:8(int) ├── key columns: [1 2] = [6 7] ├── 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(6)=0.01, null(6)=0, distinct(7)=0.01, null(7)=0, distinct(8)=0.00999995009, null(8)=0.0001, distinct(7,8)=0.00999999509, null(7,8)=0, distinct(1-3)=0.0099995001, null(1-3)=0] - ├── cost: 2120.6407 + ├── cost: 2131.2407 ├── key: (6,7) ├── fd: (1,2)-->(3), (6,7)-->(8), (1)==(6), (6)==(1), (2)==(7), (7)==(2) ├── interesting orderings: (+(1|6),+(2|7)) ├── 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] = [6 7] ├── stats: [rows=100, distinct(1)=100, null(1)=0, distinct(2)=10, null(2)=0, distinct(3)=10, null(3)=1, distinct(7)=1, null(7)=0, distinct(8)=1, null(8)=0, distinct(7,8)=1, null(7,8)=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] = [6 7] ├── 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(7)=1e-10, null(7)=0, distinct(8)=1e-10, null(8)=0, distinct(7,8)=1e-10, null(7,8)=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] = [6 7] ├── stats: [rows=0, distinct(1)=0, null(1)=0, distinct(2)=0, null(2)=0, distinct(3)=0, null(3)=0, distinct(7)=0, null(7)=0, distinct(8)=0, null(8)=0, distinct(7,8)=0, null(7,8)=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] = [6 7] ├── stats: [rows=100, distinct(1)=100, null(1)=0, distinct(2)=10, null(2)=0, distinct(3)=10, null(3)=1, distinct(7)=1, null(7)=0, distinct(8)=1, null(8)=0, distinct(7,8)=1, null(7,8)=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 f222c780084a..a47aa2c5be68 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: 15573.33 + Cost: 15595.13 ================================================================================ project ├── columns: s:4 @@ -43,7 +43,7 @@ Initial expression └── (k:1 = x:8) AND ((i:2 + 1) = 10) [outer=(1,2,8), immutable, constraints=(/1: (/NULL - ]; /8: (/NULL - ])] ================================================================================ NormalizeCmpPlusConst - Cost: 15540.00 + Cost: 15561.80 ================================================================================ project ├── columns: s:4 @@ -67,7 +67,7 @@ NormalizeCmpPlusConst + └── (k:1 = x:8) AND (i:2 = (10 - 1)) [outer=(1,2,8), immutable, constraints=(/1: (/NULL - ]; /2: (/NULL - ]; /8: (/NULL - ])] ================================================================================ FoldBinary - Cost: 12273.33 + Cost: 12295.13 ================================================================================ project ├── columns: s:4 @@ -91,7 +91,7 @@ FoldBinary + └── (k:1 = x:8) AND (i:2 = 9) [outer=(1,2,8), constraints=(/1: (/NULL - ]; /2: [/9 - /9]; /8: (/NULL - ]), fd=()-->(2)] ================================================================================ SimplifyJoinFilters - Cost: 2250.10 + Cost: 2271.90 ================================================================================ project ├── columns: s:4 @@ -117,7 +117,7 @@ SimplifyJoinFilters + └── i:2 = 9 [outer=(2), constraints=(/2: [/9 - /9]; tight), fd=()-->(2)] ================================================================================ PushFilterIntoJoinLeft - Cost: 2237.83 + Cost: 2259.63 ================================================================================ project ├── columns: s:4 @@ -149,7 +149,7 @@ PushFilterIntoJoinLeft + └── k:1 = x:8 [outer=(1,8), constraints=(/1: (/NULL - ]; /8: (/NULL - ]), fd=(1)==(8), (8)==(1)] ================================================================================ PruneJoinLeftCols - Cost: 2237.94 + Cost: 2259.74 ================================================================================ project ├── columns: s:4 @@ -191,7 +191,7 @@ PruneJoinLeftCols └── k:1 = x:8 [outer=(1,8), constraints=(/1: (/NULL - ]; /8: (/NULL - ]), fd=(1)==(8), (8)==(1)] ================================================================================ PruneSelectCols - Cost: 2197.54 + Cost: 2218.94 ================================================================================ project ├── columns: s:4 @@ -226,7 +226,7 @@ PruneSelectCols └── k:1 = x:8 [outer=(1,8), constraints=(/1: (/NULL - ]; /8: (/NULL - ]), fd=(1)==(8), (8)==(1)] ================================================================================ EliminateProject - Cost: 2197.43 + Cost: 2218.83 ================================================================================ project ├── columns: s:4 @@ -264,7 +264,7 @@ EliminateProject └── k:1 = x:8 [outer=(1,8), constraints=(/1: (/NULL - ]; /8: (/NULL - ]), fd=(1)==(8), (8)==(1)] ================================================================================ PruneJoinRightCols - Cost: 2167.13 + Cost: 2188.23 ================================================================================ project ├── columns: s:4 @@ -310,7 +310,7 @@ GenerateIndexScans (no changes) -------------------------------------------------------------------------------- ================================================================================ ReorderJoins - Cost: 2162.04 + Cost: 2183.14 ================================================================================ project ├── columns: s:4 @@ -339,7 +339,7 @@ ReorderJoins └── k:1 = x:8 [outer=(1,8), constraints=(/1: (/NULL - ]; /8: (/NULL - ]), fd=(1)==(8), (8)==(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 @@ -475,7 +475,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 @@ -509,7 +509,7 @@ SELECT s, k FROM a WHERE s='foo' AND f>100 ---- ================================================================================ Initial expression - Cost: 1145.33 + Cost: 1156.53 ================================================================================ project ├── columns: s:4!null k:1!null @@ -527,7 +527,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: 1145.34 + Cost: 1156.54 ================================================================================ project ├── columns: s:4!null k:1!null @@ -547,7 +547,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 @@ -570,7 +570,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 @@ -593,7 +593,7 @@ GeneratePartialIndexScans (no changes) -------------------------------------------------------------------------------- ================================================================================ GenerateConstrainedScans - Cost: 14.10 + Cost: 24.80 ================================================================================ project ├── columns: s:4!null k:1!null @@ -618,7 +618,7 @@ GenerateZigzagJoins (no changes) -------------------------------------------------------------------------------- ================================================================================ Final best expression - Cost: 14.10 + Cost: 24.80 ================================================================================ project ├── columns: s:4!null k:1!null @@ -636,7 +636,7 @@ SELECT * FROM a WHERE EXISTS(SELECT * FROM xy WHERE y=i) ---- ================================================================================ Initial expression - Cost: 2243.11 + Cost: 2264.91 ================================================================================ project ├── columns: k:1!null i:2 f:3 s:4 j:5 @@ -670,7 +670,7 @@ Initial expression └── y:9 = i:2 [outer=(2,9), constraints=(/2: (/NULL - ]; /9: (/NULL - ]), fd=(2)==(9), (9)==(2)] ================================================================================ PruneSelectCols - Cost: 2222.91 + Cost: 2244.51 ================================================================================ project ├── columns: k:1!null i:2 f:3 s:4 j:5 @@ -708,7 +708,7 @@ PruneSelectCols └── y:9 = i:2 [outer=(2,9), constraints=(/2: (/NULL - ]; /9: (/NULL - ]), fd=(2)==(9), (9)==(2)] ================================================================================ EliminateProject - Cost: 2213.00 + Cost: 2234.60 ================================================================================ project ├── columns: k:1!null i:2 f:3 s:4 j:5 @@ -749,7 +749,7 @@ EliminateProject + └── y:9 = i:2 [outer=(2,9), constraints=(/2: (/NULL - ]; /9: (/NULL - ]), fd=(2)==(9), (9)==(2)] ================================================================================ HoistSelectExists - Cost: 12149.64 + Cost: 12171.24 ================================================================================ project ├── columns: k:1!null i:2 f:3 s:4 j:5 @@ -797,7 +797,7 @@ HoistSelectExists + └── filters (true) ================================================================================ TryDecorrelateSelect - Cost: 2339.60 + Cost: 2361.20 ================================================================================ project - ├── columns: k:1!null i:2 f:3 s:4 j:5 @@ -838,7 +838,7 @@ TryDecorrelateSelect └── filters (true) ================================================================================ DecorrelateJoin - Cost: 2337.81 + Cost: 2359.41 ================================================================================ project - ├── columns: k:1!null i:2!null f:3 s:4 j:5 @@ -869,7 +869,7 @@ DecorrelateJoin └── filters (true) ================================================================================ PruneSemiAntiJoinRightCols - Cost: 2327.71 + Cost: 2349.21 ================================================================================ project ├── columns: k:1!null i:2 f:3 s:4 j:5 @@ -897,7 +897,7 @@ PruneSemiAntiJoinRightCols └── filters (true) ================================================================================ EliminateSelect - Cost: 2317.70 + Cost: 2339.20 ================================================================================ project ├── columns: k:1!null i:2 f:3 s:4 j:5 @@ -929,7 +929,7 @@ EliminateSelect + └── y:9 = i:2 [outer=(2,9), constraints=(/2: (/NULL - ]; /9: (/NULL - ]), fd=(2)==(9), (9)==(2)] ================================================================================ PruneJoinLeftCols - Cost: 2297.50 + Cost: 2318.80 ================================================================================ project ├── columns: k:1!null i:2 f:3 s:4 j:5 @@ -953,7 +953,7 @@ PruneJoinLeftCols └── y:9 = i:2 [outer=(2,9), constraints=(/2: (/NULL - ]; /9: (/NULL - ]), fd=(2)==(9), (9)==(2)] ================================================================================ EliminateProject - Cost: 2287.49 + Cost: 2308.79 ================================================================================ -project +semi-join (hash) @@ -991,7 +991,7 @@ ReorderJoins (no changes) -------------------------------------------------------------------------------- ================================================================================ CommuteSemiJoin - Cost: 2214.41 + Cost: 2235.71 ================================================================================ -semi-join (hash) +project @@ -1046,7 +1046,7 @@ GenerateLookupJoins (no changes) -------------------------------------------------------------------------------- ================================================================================ Final best expression - Cost: 2214.41 + Cost: 2235.71 ================================================================================ project ├── columns: k:1!null i:2 f:3 s:4 j:5 @@ -1076,7 +1076,7 @@ SELECT 5=ANY(SELECT i FROM a WHERE k=x) AS r FROM xy ---- ================================================================================ Initial expression - Cost: 2239.87 + Cost: 2261.67 ================================================================================ project ├── columns: r:12 @@ -1107,7 +1107,7 @@ Initial expression └── 5 ================================================================================ PruneSelectCols - Cost: 2189.37 + Cost: 2210.67 ================================================================================ project ├── columns: r:12 @@ -1142,7 +1142,7 @@ PruneSelectCols └── 5 ================================================================================ PruneScanCols - Cost: 2159.07 + Cost: 2180.07 ================================================================================ project ├── columns: r:12 @@ -1175,7 +1175,7 @@ PruneScanCols └── 5 ================================================================================ HoistProjectSubquery - Cost: 2181.71 + Cost: 2202.71 ================================================================================ project ├── columns: r:12 @@ -1265,7 +1265,7 @@ HoistProjectSubquery + └── case:15 [as=r:12, outer=(15)] ================================================================================ CommuteVar - Cost: 2181.71 + Cost: 2202.71 ================================================================================ project ├── columns: r:12 @@ -1333,7 +1333,7 @@ CommuteVar └── case:15 [as=r:12, outer=(15)] ================================================================================ PushSelectIntoProject - Cost: 2181.71 + Cost: 2202.71 ================================================================================ project ├── columns: r:12 @@ -1413,7 +1413,7 @@ PushSelectIntoProject └── case:15 [as=r:12, outer=(15)] ================================================================================ MergeSelects - Cost: 2181.73 + Cost: 2202.73 ================================================================================ project ├── columns: r:12 @@ -1491,7 +1491,7 @@ MergeSelects └── case:15 [as=r:12, outer=(15)] ================================================================================ EliminateSelect - Cost: 2181.71 + Cost: 2202.71 ================================================================================ project ├── columns: r:12 @@ -1572,7 +1572,7 @@ EliminateSelect └── case:15 [as=r:12, outer=(15)] ================================================================================ MergeProjects - Cost: 2181.69 + Cost: 2202.69 ================================================================================ project ├── columns: r:12 @@ -1642,7 +1642,7 @@ MergeProjects └── case:15 [as=r:12, outer=(15)] ================================================================================ FoldNonNullIsNotNull - Cost: 2181.69 + Cost: 2202.69 ================================================================================ project ├── columns: r:12 @@ -1697,7 +1697,7 @@ FoldNonNullIsNotNull └── case:15 [as=r:12, outer=(15)] ================================================================================ SimplifyAndTrue - Cost: 2181.69 + Cost: 2202.69 ================================================================================ project ├── columns: r:12 @@ -1752,7 +1752,7 @@ SimplifyAndTrue └── case:15 [as=r:12, outer=(15)] ================================================================================ TryDecorrelateProject - Cost: 2211.68 + Cost: 2232.68 ================================================================================ project ├── columns: r:12 @@ -1842,7 +1842,7 @@ TryDecorrelateProject └── case:15 [as=r:12, outer=(15)] ================================================================================ TryDecorrelateScalarGroupBy - Cost: 2271.82 + Cost: 2292.82 ================================================================================ project ├── columns: r:12 @@ -1941,7 +1941,7 @@ TryDecorrelateScalarGroupBy └── case:15 [as=r:12, outer=(15)] ================================================================================ TryDecorrelateProjectSelect - Cost: 2309.42 + Cost: 2330.42 ================================================================================ project ├── columns: r:12 @@ -2027,7 +2027,7 @@ TryDecorrelateProjectSelect └── case:15 [as=r:12, outer=(15)] ================================================================================ DecorrelateJoin - Cost: 2309.42 + Cost: 2330.42 ================================================================================ project ├── columns: r:12 @@ -2090,7 +2090,7 @@ DecorrelateJoin └── case:15 [as=r:12, outer=(15)] ================================================================================ PushFilterIntoJoinRight - Cost: 2307.63 + Cost: 2328.63 ================================================================================ project ├── columns: r:12 @@ -2165,7 +2165,7 @@ PushFilterIntoJoinRight └── case:15 [as=r:12, outer=(15)] ================================================================================ PushSelectIntoProject - Cost: 2297.64 + Cost: 2318.64 ================================================================================ project ├── columns: r:12 @@ -2240,7 +2240,7 @@ PushSelectIntoProject └── case:15 [as=r:12, outer=(15)] ================================================================================ EliminateSelect - Cost: 2294.30 + Cost: 2315.30 ================================================================================ project ├── columns: r:12 @@ -2322,7 +2322,7 @@ EliminateSelect └── case:15 [as=r:12, outer=(15)] ================================================================================ PruneJoinRightCols - Cost: 2294.30 + Cost: 2315.30 ================================================================================ project ├── columns: r:12 @@ -2392,7 +2392,7 @@ PruneJoinRightCols └── case:15 [as=r:12, outer=(15)] ================================================================================ EliminateGroupByProject - Cost: 2284.29 + Cost: 2305.29 ================================================================================ project ├── columns: r:12 @@ -2483,7 +2483,7 @@ EliminateGroupByProject └── case:15 [as=r:12, outer=(15)] ================================================================================ EliminateProject - Cost: 2274.28 + Cost: 2295.28 ================================================================================ project ├── columns: r:12 @@ -2576,7 +2576,7 @@ EliminateProject └── case:15 [as=r:12, outer=(15)] ================================================================================ EliminateSelect - Cost: 2264.27 + Cost: 2285.27 ================================================================================ project ├── columns: r:12 @@ -2661,7 +2661,7 @@ EliminateSelect └── case:15 [as=r:12, outer=(15)] ================================================================================ EliminateSelect - Cost: 2254.26 + Cost: 2275.26 ================================================================================ project ├── columns: r:12 @@ -2747,7 +2747,7 @@ EliminateSelect └── case:15 [as=r:12, outer=(15)] ================================================================================ PruneProjectCols - Cost: 2254.26 + Cost: 2275.26 ================================================================================ project ├── columns: r:12 @@ -2796,7 +2796,7 @@ PruneProjectCols └── case:15 [as=r:12, outer=(15)] ================================================================================ InlineProjectInProject - Cost: 2234.25 + Cost: 2255.25 ================================================================================ project ├── columns: r:12 @@ -2936,7 +2936,7 @@ CommuteLeftJoin (higher cost) └── CASE WHEN bool_or:14 THEN true WHEN bool_or:14 IS NULL THEN false ELSE CAST(NULL AS BOOL) END [as=r:12, outer=(14)] ================================================================================ GenerateMergeJoins - Cost: 2229.24 + Cost: 2250.24 ================================================================================ project ├── columns: r:12 @@ -3306,7 +3306,7 @@ GenerateMergeJoins (higher cost) └── CASE WHEN bool_or:14 THEN true WHEN bool_or:14 IS NULL THEN false ELSE CAST(NULL AS BOOL) END [as=r:12, outer=(14)] ================================================================================ GenerateStreamingGroupBy - Cost: 2219.09 + Cost: 2240.09 ================================================================================ project ├── columns: r:12 @@ -3354,7 +3354,7 @@ GenerateStreamingGroupBy └── CASE WHEN bool_or:14 THEN true WHEN bool_or:14 IS NULL THEN false ELSE CAST(NULL AS BOOL) END [as=r:12, outer=(14)] ================================================================================ Final best expression - Cost: 2219.09 + Cost: 2240.09 ================================================================================ project ├── columns: r:12 diff --git a/pkg/sql/opt/norm/testdata/rules/prune_cols b/pkg/sql/opt/norm/testdata/rules/prune_cols index c0c4c4e92c46..e7c87b4b86d7 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:7(int) ├── stats: [rows=1000] - ├── cost: 1074.53 + ├── cost: 1085.03 ├── prune: (7) └── window partition=() ├── columns: t.public.a.i:2(int) ntile:7(int) ├── stats: [rows=1000] - ├── cost: 1064.52 + ├── cost: 1075.02 ├── prune: (7) ├── 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:7, 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:7(int) ├── stats: [rows=1000] - ├── cost: 1074.53 + ├── cost: 1085.03 ├── prune: (7) └── window partition=() ├── columns: t.public.a.i:2(int) ntile:7(int) ├── stats: [rows=1000] - ├── cost: 1064.52 + ├── cost: 1075.02 ├── prune: (7) ├── 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:7, type=int, outer=(2)] @@ -4938,12 +4938,12 @@ WITH foo AS (SELECT * FROM a) with &1 (foo) ├── columns: i:8(int) ├── stats: [rows=1000] - ├── cost: 1094.83 + ├── cost: 1105.63 ├── prune: (8) ├── 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 486b0aeb5161..b0b1493a513e 100644 --- a/pkg/sql/opt/norm/testdata/rules/scalar +++ b/pkg/sql/opt/norm/testdata/rules/scalar @@ -1155,7 +1155,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) @@ -1163,7 +1163,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) @@ -1175,7 +1175,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) @@ -1183,7 +1183,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 76c934bec817..f731e30e54ec 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(14)=2, null(14)=0] - ├── cost: 1046.8975 + ├── cost: 1057.0975 ├── key: (14) ├── 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.7875 + │ ├── cost: 1056.9875 │ ├── key: () │ ├── fd: ()-->(1) │ ├── values @@ -582,7 +582,7 @@ with &2 (cte) │ ├── columns: p:7(int!null) │ ├── cardinality: [0 - 1] │ ├── stats: [rows=1e-10] - │ ├── cost: 1046.7575 + │ ├── cost: 1056.9575 │ ├── key: () │ ├── fd: ()-->(7) │ ├── cte-uses @@ -602,7 +602,7 @@ with &2 (cte) │ ├── scan t.public.parent │ │ ├── columns: t.public.parent.p:8(int!null) │ │ ├── stats: [rows=1000, distinct(8)=1000, null(8)=0] - │ │ ├── cost: 1034.21 + │ │ ├── cost: 1044.41 │ │ ├── key: (8) │ │ ├── prune: (8) │ │ ├── interesting orderings: (+8) diff --git a/pkg/sql/opt/opbench/testdata/hash-set-op.csv b/pkg/sql/opt/opbench/testdata/hash-set-op.csv index 9659dae3cfc7..cd61002421f4 100644 --- a/pkg/sql/opt/opbench/testdata/hash-set-op.csv +++ b/pkg/sql/opt/opbench/testdata/hash-set-op.csv @@ -3,25 +3,25 @@ rows,num_cols,estimated,actual 1000000,1,2768732.717247,1.895822 2000000,1,6474966.779587,3.764830 3000000,1,11118710.217022,6.387358 -4000000,1,13392461.154531,7.309750 -5000000,1,15978715.217072,8.269335 -6000000,1,18877472.404644,9.090714 -7000000,1,21432476.154681,9.871740 -8000000,1,23612476.154681,10.739554 -9000000,1,25792476.154681,12.120099 -10000000,1,27972476.154681,13.059812 -11000000,1,30152476.154681,14.094840 -12000000,1,32332476.154681,14.872081 +4000000,1,13392466.654531,7.309750 +5000000,1,15978720.717072,8.269335 +6000000,1,18877477.904644,9.090714 +7000000,1,21432481.654681,9.871740 +8000000,1,23612481.654681,10.739554 +9000000,1,25792481.654681,12.120099 +10000000,1,27972481.654681,13.059812 +11000000,1,30152481.654681,14.094840 +12000000,1,32332481.654681,14.872081 10,2,31.230000,0.001430 1000000,2,2788732.717247,2.569923 2000000,2,6514966.779587,5.832292 3000000,2,11178710.217022,9.324068 -4000000,2,13462461.154531,11.179740 -5000000,2,16058715.217072,13.026902 -6000000,2,18967472.404644,14.482560 -7000000,2,21532476.154681,16.357014 -8000000,2,23722476.154681,18.028023 -9000000,2,25912476.154681,19.541359 -10000000,2,28102476.154681,21.582277 -11000000,2,30292476.154681,23.203637 -12000000,2,32482476.154681,24.602979 +4000000,2,13462466.704531,11.179740 +5000000,2,16058720.767072,13.026902 +6000000,2,18967477.954644,14.482560 +7000000,2,21532481.704681,16.357014 +8000000,2,23722481.704681,18.028023 +9000000,2,25912481.704681,19.541359 +10000000,2,28102481.704681,21.582277 +11000000,2,30292481.704681,23.203637 +12000000,2,32482481.704681,24.602979 diff --git a/pkg/sql/opt/opbench/testdata/streaming-set-op.csv b/pkg/sql/opt/opbench/testdata/streaming-set-op.csv index 6eb7c13a7870..f663196d6c4a 100644 --- a/pkg/sql/opt/opbench/testdata/streaming-set-op.csv +++ b/pkg/sql/opt/opbench/testdata/streaming-set-op.csv @@ -3,12 +3,12 @@ rows,num_cols,estimated,actual 1000000,1,2280008.030000,0.927285 2000000,1,4560008.030000,1.837067 3000000,1,6840008.030000,2.763610 -4000000,1,8010008.030000,3.726523 -5000000,1,9180008.030000,4.647007 -6000000,1,10350008.030000,5.561615 -7000000,1,11520008.030000,6.482572 -8000000,1,12690008.030000,7.488520 -9000000,1,13860008.030000,8.383537 -10000000,1,15030008.030000,9.341458 -11000000,1,16200008.030000,10.282343 -12000000,1,17370008.030000,11.209018 +4000000,1,8010013.530000,3.726523 +5000000,1,9180013.530000,4.647007 +6000000,1,10350013.530000,5.561615 +7000000,1,11520013.530000,6.482572 +8000000,1,12690013.530000,7.488520 +9000000,1,13860013.530000,8.383537 +10000000,1,15030013.530000,9.341458 +11000000,1,16200013.530000,10.282343 +12000000,1,17370013.530000,11.209018 diff --git a/pkg/sql/opt/optbuilder/testdata/aggregate b/pkg/sql/opt/optbuilder/testdata/aggregate index dedf910280b5..3b415c2b4f13 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: 1144.98625 + ├── cost: 1155.78625 ├── key: (1) ├── fd: (1)-->(2) ├── interesting orderings: (+1) └── 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: 1104.82 + ├── cost: 1115.62 ├── 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) t.public.xyz.tableoid:5(oid) ├── stats: [rows=1000, distinct(1,2)=1000, null(1,2)=0] - ├── cost: 1094.81 + ├── cost: 1105.61 ├── key: (1) ├── fd: (1)-->(2-5) ├── prune: (1-5) diff --git a/pkg/sql/opt/optgen/exprgen/testdata/explain b/pkg/sql/opt/optgen/exprgen/testdata/explain index 8b1caff54096..82f2a4b0325c 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: 1314.09194 + ├── cost: 1324.69194 └── sort ├── columns: a:1(int) [hidden: t.public.abc.b:2(int)] ├── stats: [rows=1000] - ├── cost: 1314.08194 + ├── cost: 1324.68194 ├── 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 489ae18c1d16..87fb01af2001 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:7(int!null) t.public.def.e:8(int) t.public.def.f:9(int) ├── stats: [rows=9801, distinct(1)=99, null(1)=0, distinct(7)=99, null(7)=0] - ├── cost: 2297.58625 + ├── cost: 2318.98625 ├── fd: (1)==(7), (7)==(1) ├── prune: (2,3,8,9) ├── 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-6) ├── scan t.public.def │ ├── columns: t.public.def.d:7(int) t.public.def.e:8(int) t.public.def.f:9(int) │ ├── stats: [rows=1000, distinct(7)=100, null(7)=10] - │ ├── cost: 1084.71 + │ ├── cost: 1095.41 │ ├── prune: (7-9) │ └── unfiltered-cols: (7-12) └── filters @@ -50,11 +50,11 @@ left-join (lookup t.public.abc@ab) ├── columns: t.public.abc.a:7(int) t.public.abc.b:8(int) ├── key columns: [7] = [7] ├── stats: [rows=3333.33333, distinct(7)=100, null(7)=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,7), constraints=(/2: (/NULL - ]; /7: (/NULL - ])] @@ -80,31 +80,31 @@ inner-join (merge) ├── left ordering: +1 ├── right ordering: +7 ├── stats: [rows=9801, distinct(1)=99, null(1)=0, distinct(7)=99, null(7)=0] - ├── cost: 2786.38387 + ├── cost: 2807.78387 ├── fd: (1)==(7), (7)==(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.18194 + │ ├── cost: 1344.88194 │ ├── 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:7(int) t.public.def.e:8(int) t.public.def.f:9(int) │ ├── stats: [rows=1000, distinct(7)=100, null(7)=10] - │ ├── cost: 1334.18194 + │ ├── cost: 1344.88194 │ ├── ordering: +7 │ ├── prune: (7-9) │ └── scan t.public.def │ ├── columns: t.public.def.d:7(int) t.public.def.e:8(int) t.public.def.f:9(int) │ ├── stats: [rows=1000, distinct(7)=100, null(7)=10] - │ ├── cost: 1084.71 + │ ├── cost: 1095.41 │ └── prune: (7-9) └── 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:7(int) t.public.def.e:8(int) t.public.def.f:9(int) ├── immutable ├── stats: [rows=333333.333] - ├── cost: 5670.94479 + ├── cost: 5692.34479 ├── prune: (9) ├── 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.52409 + │ ├── cost: 1235.22409 │ ├── 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:7(int) t.public.def.e:8(int) t.public.def.f:9(int) │ ├── outer: (1) │ ├── immutable │ ├── stats: [rows=333.333333, distinct(1)=1, null(1)=0] - │ ├── cost: 1094.73 + │ ├── cost: 1105.43 │ ├── prune: (9) │ ├── scan t.public.def │ │ ├── columns: t.public.def.d:7(int) t.public.def.e:8(int) t.public.def.f:9(int) │ │ ├── stats: [rows=1000] - │ │ ├── cost: 1084.71 + │ │ ├── cost: 1095.41 │ │ └── prune: (7-9) │ └── filters │ └── eq [type=bool, outer=(1,7,8), immutable, constraints=(/1: (/NULL - ])] diff --git a/pkg/sql/opt/optgen/exprgen/testdata/limit b/pkg/sql/opt/optgen/exprgen/testdata/limit index bd1b3afbf517..527b1501fa87 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.19194 + ├── cost: 1324.79194 ├── interesting orderings: (+1,+2) ├── sort │ ├── columns: t.public.abc.a:1(int) t.public.abc.b:2(int) │ ├── stats: [rows=1000] - │ ├── cost: 1314.08194 + │ ├── cost: 1324.68194 │ ├── 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 4dfc5da23c13..f0245086fd4a 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: (+2 opt(1)) ├── 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/optgen/exprgen/testdata/set b/pkg/sql/opt/optgen/exprgen/testdata/set index bd7f6943ffa7..27b6c396fdeb 100644 --- a/pkg/sql/opt/optgen/exprgen/testdata/set +++ b/pkg/sql/opt/optgen/exprgen/testdata/set @@ -24,26 +24,26 @@ intersect ├── right columns: t.public.def.d:7(int) t.public.def.e:8(int) t.public.def.f:9(int) ├── internal-ordering: +1,+2,+3 ├── stats: [rows=1000, distinct(1-3)=1000, null(1-3)=0.001] - ├── cost: 2440.9643 + ├── cost: 2462.3643 ├── key: (1-3) ├── interesting orderings: (+1,+2,+3) ├── scan t.public.abc@abc_idx │ ├── columns: t.public.abc.a:1(int) t.public.abc.b:2(int) t.public.abc.c:3(int) │ ├── stats: [rows=1000, distinct(1-3)=1000, null(1-3)=0.001] - │ ├── cost: 1084.71 + │ ├── cost: 1095.41 │ ├── ordering: +1,+2,+3 │ ├── prune: (1-3) │ └── interesting orderings: (+1,+2,+3) └── sort ├── columns: t.public.def.d:7(int) t.public.def.e:8(int) t.public.def.f:9(int) ├── stats: [rows=1000, distinct(7-9)=1000, null(7-9)=0.001] - ├── cost: 1346.2443 + ├── cost: 1356.9443 ├── ordering: +7,+8,+9 ├── prune: (7-9) └── scan t.public.def ├── columns: t.public.def.d:7(int) t.public.def.e:8(int) t.public.def.f:9(int) ├── stats: [rows=1000, distinct(7-9)=1000, null(7-9)=0.001] - ├── cost: 1084.71 + ├── cost: 1095.41 └── prune: (7-9) expr @@ -62,17 +62,17 @@ intersect ├── left columns: t.public.abc.a:1(int) t.public.abc.b:2(int) t.public.abc.c:3(int) ├── right columns: t.public.def.d:7(int) t.public.def.e:8(int) t.public.def.f:9(int) ├── stats: [rows=1000, distinct(1-3)=1000, null(1-3)=0.001] - ├── cost: 2199.86875 + ├── cost: 2221.26875 ├── key: (1-3) ├── interesting orderings: (+1,+2,+3) ├── scan t.public.abc@abc_idx │ ├── columns: t.public.abc.a:1(int) t.public.abc.b:2(int) t.public.abc.c:3(int) │ ├── stats: [rows=1000, distinct(1-3)=1000, null(1-3)=0.001] - │ ├── cost: 1084.71 + │ ├── cost: 1095.41 │ ├── prune: (1-3) │ └── interesting orderings: (+1,+2,+3) └── scan t.public.def ├── columns: t.public.def.d:7(int) t.public.def.e:8(int) t.public.def.f:9(int) ├── stats: [rows=1000, distinct(7-9)=1000, null(7-9)=0.001] - ├── cost: 1084.71 + ├── cost: 1095.41 └── prune: (7-9) 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 d47676452376..36f805322e89 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: 1084.74 + Cost: 1095.34 ================================================================================ 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: 2239.79 + Cost: 2261.39 ================================================================================ project ├── columns: id:1(int!null) customer_id:2(int) status:3(string!null) id:6(int) name:7(string) address:8(string) @@ -240,7 +240,7 @@ Initial expression └── variable: customers.id:6 [type=int] ================================================================================ NormalizeInConst - Cost: 2239.79 + Cost: 2261.39 ================================================================================ project ├── columns: id:1(int!null) customer_id:2(int) status:3(string!null) id:6(int) name:7(string) address:8(string) @@ -274,7 +274,7 @@ NormalizeInConst └── variable: customers.id:6 [type=int] ================================================================================ PruneJoinLeftCols - Cost: 2219.59 + Cost: 2240.99 ================================================================================ project ├── columns: id:1(int!null) customer_id:2(int) status:3(string!null) id:6(int) name:7(string) address:8(string) @@ -310,7 +310,7 @@ PruneJoinLeftCols └── variable: customers.id:6 [type=int] ================================================================================ PruneJoinRightCols - Cost: 2199.39 + Cost: 2220.59 ================================================================================ project ├── columns: id:1(int!null) customer_id:2(int) status:3(string!null) id:6(int) name:7(string) address:8(string) @@ -346,7 +346,7 @@ PruneJoinRightCols └── variable: customers.id:6 [type=int] ================================================================================ EliminateProject - Cost: 2189.38 + Cost: 2210.58 ================================================================================ -project +left-join (hash) @@ -517,7 +517,7 @@ GenerateMergeJoins (higher cost) └── filters (true) ================================================================================ Final best expression - Cost: 2189.38 + Cost: 2210.58 ================================================================================ left-join (hash) ├── columns: id:1(int!null) customer_id:2(int) status:3(string!null) id:6(int) name:7(string) address:8(string) @@ -560,7 +560,7 @@ SELECT * FROM comp WHERE k=1 ---- ================================================================================ Initial expression - Cost: 1104.94 + Cost: 1115.74 ================================================================================ project ├── columns: k:1(int!null) c:2(bool) @@ -587,7 +587,7 @@ Initial expression └── const: 1 [type=int] ================================================================================ NormalizeInConst - Cost: 1104.94 + Cost: 1115.74 ================================================================================ project ├── columns: k:1(int!null) c:2(bool) @@ -616,7 +616,7 @@ NormalizeInConst └── const: 1 [type=int] ================================================================================ PruneSelectCols - Cost: 1074.64 + Cost: 1085.14 ================================================================================ project ├── columns: k:1(int!null) c:2(bool) @@ -647,7 +647,7 @@ PruneSelectCols └── const: 1 [type=int] ================================================================================ EliminateProject - Cost: 1074.53 + Cost: 1085.03 ================================================================================ -project +select @@ -716,7 +716,7 @@ GenerateConstrainedScans (no changes) -------------------------------------------------------------------------------- ================================================================================ FoldComparison - Cost: 14.51 + Cost: 25.01 ================================================================================ -select +scan comp@secondary @@ -744,7 +744,7 @@ GenerateZigzagJoins (no changes) -------------------------------------------------------------------------------- ================================================================================ Final best expression - Cost: 14.51 + Cost: 25.01 ================================================================================ scan comp@secondary ├── columns: k:1(int!null) c:2(bool) @@ -764,7 +764,7 @@ SELECT i FROM (SELECT i FROM t WHERE i > 10 AND i < 20) AS t2 WHERE i = 5 ---- ================================================================================ Initial expression - Cost: 1086.46 + Cost: 1097.06 ================================================================================ select ├── columns: i:1(int!null) @@ -793,7 +793,7 @@ Initial expression └── const: 5 [type=int] ================================================================================ SimplifySelectFilters - Cost: 1091.34 + Cost: 1101.94 ================================================================================ select ├── columns: i:1(int!null) @@ -828,7 +828,7 @@ SimplifySelectFilters └── const: 5 [type=int] ================================================================================ ConsolidateSelectFilters - Cost: 1086.46 + Cost: 1097.06 ================================================================================ select ├── columns: i:1(int!null) @@ -864,7 +864,7 @@ ConsolidateSelectFilters └── const: 5 [type=int] ================================================================================ PruneSelectCols - Cost: 1056.16 + Cost: 1066.46 ================================================================================ select ├── columns: i:1(int!null) @@ -896,7 +896,7 @@ PruneSelectCols └── const: 5 [type=int] ================================================================================ EliminateProject - Cost: 1055.25 + Cost: 1065.55 ================================================================================ select ├── columns: i:1(int!null) @@ -934,7 +934,7 @@ EliminateProject └── const: 5 [type=int] ================================================================================ MergeSelects - Cost: 1054.34 + Cost: 1064.64 ================================================================================ select ├── columns: i:1(int!null) @@ -968,7 +968,7 @@ MergeSelects └── const: 5 [type=int] ================================================================================ InlineConstVar - Cost: 1054.34 + Cost: 1064.64 ================================================================================ select ├── columns: i:1(int!null) @@ -992,7 +992,7 @@ InlineConstVar └── const: 5 [type=int] ================================================================================ FoldComparison - Cost: 1054.34 + Cost: 1064.64 ================================================================================ select ├── columns: i:1(int!null) @@ -1016,7 +1016,7 @@ FoldComparison └── const: 5 [type=int] ================================================================================ FoldComparison - Cost: 1054.34 + Cost: 1064.64 ================================================================================ select ├── columns: i:1(int!null) @@ -1037,7 +1037,7 @@ FoldComparison └── const: 5 [type=int] ================================================================================ SimplifyAndTrue - Cost: 1054.34 + Cost: 1064.64 ================================================================================ select ├── columns: i:1(int!null) @@ -1056,7 +1056,7 @@ SimplifyAndTrue └── const: 5 [type=int] ================================================================================ SimplifyRange - Cost: 1054.34 + Cost: 1064.64 ================================================================================ select ├── columns: i:1(int!null) @@ -1073,7 +1073,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 5d8fbc852e93..31bda85fb72a 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,17 @@ 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. + 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 @@ -640,6 +652,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) } @@ -1030,6 +1047,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) @@ -1257,6 +1280,27 @@ func (c *coster) rowBufferCost(rowCount float64) memo.Cost { return memo.Cost(rowCount) * spillCostFactor * fraction } +// 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 b19a09b9068b..84164f196869 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:7!null min:8!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.87625 + ├── cost: 1155.57625 ├── key: (2,3) ├── fd: (2,3)-->(7,8) ├── 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 38fab6132e35..364b88a72879 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:7!null ├── immutable ├── stats: [rows=99] - ├── cost: 2153.715 + ├── cost: 2174.715 ├── fd: (1)==(7), (7)==(1) └── inner-join (hash) ├── columns: k:1!null d:4!null x:7!null ├── multiplicity: left-rows(zero-or-one), right-rows(zero-or-more) ├── immutable ├── stats: [rows=99, distinct(1)=10, null(1)=0, distinct(7)=10, null(7)=0] - ├── cost: 2152.715 + ├── cost: 2173.715 ├── fd: ()-->(4), (1)==(7), (7)==(1) ├── scan b │ ├── columns: x:7 │ ├── stats: [rows=1000, distinct(7)=100, null(7)=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: +7 ├── stats: [rows=990, distinct(1)=99, null(1)=0, distinct(7)=99, null(7)=0] - ├── cost: 2378.30194 + ├── cost: 2399.20194 ├── fd: (1)==(7), (7)==(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:7 │ ├── stats: [rows=1000, distinct(7)=100, null(7)=10] - │ ├── cost: 1283.88194 + │ ├── cost: 1294.28194 │ ├── ordering: +7 │ └── scan b │ ├── columns: x:7 │ ├── stats: [rows=1000, distinct(7)=100, null(7)=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] = [6] ├── lookup columns are key ├── stats: [rows=990, distinct(1)=99, null(1)=0, distinct(6)=99, null(6)=0] - ├── cost: 7093.82 + ├── cost: 7104.22 ├── fd: (1)==(6), (6)==(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:7 │ ├── stats: [rows=1000, distinct(7)=100, null(7)=10] - │ └── cost: 1054.41 + │ └── cost: 1064.81 └── filters └── k:1 = x:7 [outer=(1,7), constraints=(/1: (/NULL - ]; /7: (/NULL - ]), fd=(1)==(7), (7)==(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,6) ├── fd: (1)-->(2), (6)-->(7) ├── 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:12) │ ├── stats: [rows=10000, distinct(1)=999.956829, null(1)=0, distinct(11)=999.956829, null(11)=0] - │ ├── cost: 41454.42 + │ ├── cost: 41464.82 │ ├── key: (1,11) │ ├── 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:6!null g2.geom:7 │ ├── stats: [rows=1000, distinct(6)=1000, null(6)=0] - │ ├── cost: 1054.41 + │ ├── cost: 1064.81 │ ├── key: (6) │ └── fd: (6)-->(7) └── filters @@ -213,16 +213,16 @@ inner-join (lookup a) ├── key columns: [8] = [1] ├── lookup columns are key ├── stats: [rows=10000, distinct(1)=1000, null(1)=0, distinct(8)=1000, null(8)=0] - ├── cost: 71514.54 + ├── cost: 71525.04 ├── fd: (1)-->(2-4), (1)==(8), (8)==(1) ├── select │ ├── columns: x:7!null z:8!null │ ├── stats: [rows=10000, distinct(7)=1000, null(7)=0, distinct(8)=1000, null(8)=0] - │ ├── cost: 10614.53 + │ ├── cost: 10625.03 │ ├── scan b │ │ ├── columns: x:7 z:8!null │ │ ├── stats: [rows=10000, distinct(7)=1000, null(7)=0, distinct(8)=1000, null(8)=0] - │ │ └── cost: 10514.51 + │ │ └── cost: 10525.01 │ └── filters │ └── (x:7 > 0) AND (x:7 <= 5000) [outer=(7), constraints=(/7: [/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:8!null b:9!null c:10!null ├── key columns: [1 2 3] = [8 9 10] ├── stats: [rows=500.488759, distinct(1)=1, null(1)=0, distinct(2)=1, null(2)=0, distinct(3)=25, null(3)=0, distinct(8)=1, null(8)=0, distinct(9)=1, null(9)=0, distinct(10)=25, null(10)=0] - ├── cost: 3169.97 + ├── cost: 3180.87 ├── fd: ()-->(1,2,8,9), (1)==(8), (8)==(1), (2)==(9), (9)==(2), (3)==(10), (10)==(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:14!null b:15!null c:16!null ├── key columns: [1 2 3] = [14 15 16] ├── 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(14)=0.9000001, null(14)=0, distinct(15)=0.9000001, null(15)=0, distinct(16)=0.88403183, null(16)=0] - ├── cost: 12243.635 + ├── cost: 12255.735 ├── fd: ()-->(1,2,5-10,14,15), (1)==(14), (14)==(1), (2)==(15), (15)==(2), (3)==(16), (16)==(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 77eba30ee79e..0d6b266ffa05 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:5!null ├── stats: [rows=1000, distinct(1)=1000, null(1)=0, distinct(5)=1000, null(5)=0] - ├── cost: 2378.24819 + ├── cost: 2398.84819 ├── key: (5) ├── fd: (1)-->(2), (1)==(5), (5)==(1) ├── ordering: +2 @@ -30,19 +30,19 @@ sort ├── columns: a.x:1!null y:2 b.x:5!null ├── multiplicity: left-rows(zero-or-one), right-rows(zero-or-one) ├── stats: [rows=1000, distinct(1)=1000, null(1)=0, distinct(5)=1000, null(5)=0] - ├── cost: 2128.77625 + ├── cost: 2149.37625 ├── key: (5) ├── fd: (1)-->(2), (1)==(5), (5)==(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:5!null │ ├── stats: [rows=1000, distinct(5)=1000, null(5)=0] - │ ├── cost: 1034.21 + │ ├── cost: 1044.41 │ └── key: (5) └── filters └── a.x:1 = b.x:5 [outer=(1,5), constraints=(/1: (/NULL - ]; /5: (/NULL - ]), fd=(1)==(5), (5)==(1)] diff --git a/pkg/sql/opt/xform/testdata/coster/project b/pkg/sql/opt/xform/testdata/coster/project index 8648a71530fa..490be3f7718f 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?":7 ├── immutable ├── stats: [rows=1000] - ├── cost: 1104.72 + ├── cost: 1115.42 ├── key: (1) ├── fd: (1)-->(2,7) ├── 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?":7!null "?column?":8 ├── immutable ├── stats: [rows=1000] - ├── cost: 1114.72 + ├── cost: 1125.42 ├── key: (1) ├── fd: (1)-->(7,8) ├── 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..e0875a38d06d 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,176 @@ 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)) +---- + +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": [ + "x", + "y" + ], + "created_at": "2021-06-28 14:20:18.273949", + "distinct_count": 3, + "histo_col_type": "", + "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 + }, + { + "columns": [ + "y", + "v" + ], + "created_at": "2021-06-28 14:20:18.273949", + "distinct_count": 3, + "histo_col_type": "", + "name": "foo", + "null_count": 0, + "row_count": 3 + } +]' +---- + +opt +UPSERT INTO t64570 VALUES (10, 10, 10) +---- +upsert t64570 + ├── columns: + ├── arbiter indexes: primary + ├── canary column: x:9 + ├── fetch columns: x:9 y:10 v:11 + ├── insert-mapping: + │ ├── column1:6 => x:1 + │ ├── column2:7 => y:2 + │ └── column3:8 => v:3 + ├── update-mapping: + │ └── column3:8 => v:3 + ├── cardinality: [0 - 0] + ├── volatile, mutations + ├── stats: [rows=0] + ├── cost: 5.14883333 + └── left-join (cross) + ├── columns: column1:6!null column2:7!null column3:8!null x:9 y:10 v:11 + ├── cardinality: [1 - 1] + ├── multiplicity: left-rows(exactly-one), right-rows(exactly-one) + ├── stats: [rows=1] + ├── cost: 5.13883333 + ├── key: () + ├── fd: ()-->(6-11) + ├── values + │ ├── columns: column1:6!null column2:7!null column3:8!null + │ ├── cardinality: [1 - 1] + │ ├── stats: [rows=1] + │ ├── cost: 0.02 + │ ├── key: () + │ ├── fd: ()-->(6-8) + │ └── (10, 10, 10) + ├── scan t64570 + │ ├── columns: x:9!null y:10!null v:11 + │ ├── constraint: /9/10: [/10/10 - /10/10] + │ ├── cardinality: [0 - 1] + │ ├── stats: [rows=0.933333333, distinct(9)=0.933333333, null(9)=0, distinct(10)=0.933333333, null(10)=0, distinct(9,10)=0.933333333, null(9,10)=0] + │ ├── cost: 5.07 + │ ├── key: () + │ └── fd: ()-->(9-11) + └── filters (true) diff --git a/pkg/sql/opt/xform/testdata/coster/select b/pkg/sql/opt/xform/testdata/coster/select index 11ebb5ed8387..e79900e9b949 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: 535014.65 + ├── cost: 535025.25 ├── key: (1) ├── project │ ├── columns: id:1!null │ ├── cardinality: [0 - 0] │ ├── stats: [rows=0] - │ ├── cost: 535014.64 + │ ├── cost: 535025.24 │ ├── key: (1) │ ├── limit hint: 10.00 │ └── select │ ├── columns: id:1!null geog:2 crdb_internal_mvcc_timestamp:3 tableoid:4 │ ├── cardinality: [0 - 0] │ ├── stats: [rows=0] - │ ├── cost: 535014.63 + │ ├── cost: 535025.23 │ ├── key: (1) │ ├── fd: (1)-->(2-4) │ ├── limit hint: 10.00 │ ├── scan g │ │ ├── columns: id:1!null geog:2 crdb_internal_mvcc_timestamp:3 tableoid:4 │ │ ├── stats: [rows=500000] - │ │ ├── cost: 530014.61 + │ │ ├── cost: 530025.21 │ │ ├── key: (1) │ │ └── fd: (1)-->(2-4) │ └── filters diff --git a/pkg/sql/opt/xform/testdata/coster/set b/pkg/sql/opt/xform/testdata/coster/set index ff407e5fc2c0..b069faeefa6d 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:7 z:8 ├── stats: [rows=2000, distinct(12,13)=2000, null(12,13)=0] - ├── cost: 2179.73501 + ├── cost: 2200.83501 ├── key: (12,13) ├── 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:7 z:8!null ├── stats: [rows=1000, distinct(7,8)=1000, null(7,8)=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:7 z:8 ├── 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:7 z:8!null ├── stats: [rows=1000] - └── cost: 1064.51 + └── cost: 1075.01 opt SELECT k, i FROM a INTERSECT SELECT * FROM b @@ -55,19 +55,19 @@ intersect-all ├── left columns: k:1 i:2 ├── right columns: x:7 z:8 ├── stats: [rows=1000] - ├── cost: 2169.27625 + ├── cost: 2190.37625 ├── key: (1) ├── fd: (1)-->(2) ├── 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:7 z:8!null ├── stats: [rows=1000] - └── cost: 1064.51 + └── cost: 1075.01 opt SELECT k, i FROM a INTERSECT ALL SELECT * FROM b @@ -77,19 +77,19 @@ intersect-all ├── left columns: k:1 i:2 ├── right columns: x:7 z:8 ├── stats: [rows=1000] - ├── cost: 2169.27625 + ├── cost: 2190.37625 ├── key: (1) ├── fd: (1)-->(2) ├── 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:7 z:8!null ├── stats: [rows=1000] - └── cost: 1064.51 + └── cost: 1075.01 opt SELECT k, i FROM a EXCEPT SELECT * FROM b @@ -99,19 +99,19 @@ except-all ├── left columns: k:1 i:2 ├── right columns: x:7 z:8 ├── stats: [rows=1000] - ├── cost: 2169.27625 + ├── cost: 2190.37625 ├── key: (1) ├── fd: (1)-->(2) ├── 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:7 z:8!null ├── stats: [rows=1000] - └── cost: 1064.51 + └── cost: 1075.01 opt SELECT k, i FROM a EXCEPT ALL SELECT * FROM b @@ -121,16 +121,16 @@ except-all ├── left columns: k:1 i:2 ├── right columns: x:7 z:8 ├── stats: [rows=1000] - ├── cost: 2169.27625 + ├── cost: 2190.37625 ├── key: (1) ├── fd: (1)-->(2) ├── 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:7 z:8!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 935f26660af4..29485d1b7afe 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.98194 + ├── cost: 1304.48194 ├── 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.2443 + ├── cost: 1356.9443 ├── 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: 13409.3394 + ├── cost: 13420.0394 ├── 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, distinct(1,2)=4, null(1,2)=0] - ├── cost: 11282.8076 + ├── cost: 11293.5076 ├── 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, distinct(1,2)=4, null(1,2)=0] - ├── cost: 10804.03 + ├── cost: 10814.73 ├── fd: (1)==(2), (2)==(1) ├── ordering: +(1|2) [actual: +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 089c056c1fd6..3097bd0c2dcf 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] = [7] ├── stats: [rows=100, distinct(2)=1, null(2)=0, distinct(7)=1, null(7)=0] - ├── cost: 417.58 + ├── cost: 428.18 ├── key: (1,6) ├── fd: ()-->(2,7), (1)-->(3), (2,3)~~>(1), (2)==(7), (7)==(2) ├── prune: (1,3,6) @@ -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] = [7] ├── stats: [rows=100, distinct(2)=1, null(2)=0, distinct(7)=1, null(7)=0] - ├── cost: 417.58 + ├── cost: 428.18 ├── key: (1,6) ├── fd: ()-->(2,7), (1)-->(3), (2,3)~~>(1), (2)==(7), (7)==(2) ├── prune: (1,3,6) @@ -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:13(string) t.public.abc_part.a:14(int) t.public.abc_part.b:15(int) t.public.abc_part.c:16(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) @@ -724,7 +724,7 @@ locality-optimized-search │ ├── constraint: /7/9/10: [/'east'/1/'foo' - /'east'/1/'foo'] │ ├── cardinality: [0 - 1] │ ├── stats: [rows=0.9001, distinct(7)=0.9001, null(7)=0, distinct(9)=0.9001, null(9)=0, distinct(10)=0.9001, null(10)=0, distinct(7,9,10)=0.9001, null(7,9,10)=0] - │ ├── cost: 1.691372 + │ ├── cost: 1.73 │ ├── key: () │ ├── fd: ()-->(7-10) │ └── prune: (7-10) @@ -733,7 +733,7 @@ locality-optimized-search ├── constraint: /13/15/16: [/'west'/1/'foo' - /'west'/1/'foo'] ├── cardinality: [0 - 1] ├── stats: [rows=0.9001, distinct(13)=0.9001, null(13)=0, distinct(15)=0.9001, null(15)=0, distinct(16)=0.9001, null(16)=0, distinct(13,15,16)=0.9001, null(13,15,16)=0] - ├── cost: 1.691372 + ├── cost: 1.73 ├── key: () ├── fd: ()-->(13-16) └── prune: (13-16) @@ -752,7 +752,7 @@ anti-join (lookup abc_part@bc_idx [as=a2]) │ └── a2.r:7 = 'west' [outer=(7), constraints=(/7: [/'west' - /'west']; tight), fd=()-->(7)] ├── 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]) @@ -763,7 +763,7 @@ anti-join (lookup abc_part@bc_idx [as=a2]) │ │ └── a2.r:7 = 'east' [outer=(7), constraints=(/7: [/'east' - /'east']; tight), fd=()-->(7)] │ ├── 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 @@ -772,7 +772,7 @@ anti-join (lookup abc_part@bc_idx [as=a2]) │ │ ├── right columns: a1.r:19 a1.a:20 a1.b:21 a1.c:22 │ │ ├── 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] @@ -780,7 +780,7 @@ anti-join (lookup abc_part@bc_idx [as=a2]) │ │ │ ├── constraint: /13/15/16: [/'east'/1/'foo' - /'east'/1/'foo'] │ │ │ ├── cardinality: [0 - 1] │ │ │ ├── stats: [rows=0.9001, distinct(13)=0.9001, null(13)=0, distinct(15)=0.9001, null(15)=0, distinct(16)=0.9001, null(16)=0, distinct(13,15,16)=0.9001, null(13,15,16)=0] - │ │ │ ├── cost: 1.691372 + │ │ │ ├── cost: 1.73 │ │ │ ├── key: () │ │ │ └── fd: ()-->(13-16) │ │ └── scan abc_part@bc_idx [as=a1] @@ -788,7 +788,7 @@ anti-join (lookup abc_part@bc_idx [as=a2]) │ │ ├── constraint: /19/21/22: [/'west'/1/'foo' - /'west'/1/'foo'] │ │ ├── cardinality: [0 - 1] │ │ ├── stats: [rows=0.9001, distinct(19)=0.9001, null(19)=0, distinct(21)=0.9001, null(21)=0, distinct(22)=0.9001, null(22)=0, distinct(19,21,22)=0.9001, null(19,21,22)=0] - │ │ ├── cost: 1.691372 + │ │ ├── cost: 1.73 │ │ ├── key: () │ │ └── fd: ()-->(19-22) │ └── filters (true) diff --git a/pkg/sql/opt/xform/testdata/physprops/ordering b/pkg/sql/opt/xform/testdata/physprops/ordering index 07e076b243d0..7475dc80b7f6 100644 --- a/pkg/sql/opt/xform/testdata/physprops/ordering +++ b/pkg/sql/opt/xform/testdata/physprops/ordering @@ -306,25 +306,25 @@ memo (optimized, ~5KB, required=[presentation: y:2,z:7] [ordering: +1,-2]) ├── G1: (project G2 G3 x y) │ ├── [presentation: y:2,z:7] [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) @@ -359,25 +359,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.30 + │ │ └── cost: 1178.00 │ └── [] │ ├── best: (project G2 G3 y z) - │ └── cost: 1098.07 + │ └── cost: 1108.77 ├── G2: (select G4 G5) │ ├── [ordering: +2] │ │ ├── best: (sort G2) - │ │ └── cost: 1167.29 + │ │ └── cost: 1177.99 │ └── [] │ ├── 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.18 + │ │ └── cost: 1344.88 │ └── [] │ ├── best: (scan a,cols=(1-3)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G5: (filters G6) ├── G6: (gt G7 G8) ├── G7: (variable x) @@ -670,14 +670,14 @@ memo (optimized, ~3KB, required=[presentation: info:7]) ├── G1: (explain G2 [presentation: x:1,y:2,z:3,s:4] [ordering: +2]) │ └── [presentation: info:7] │ ├── 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.29 + │ └── cost: 1365.09 └── G2: (scan a,cols=(1-4)) ├── [presentation: x:1,y:2,z:3,s:4] [ordering: +2] │ ├── best: (sort G2) - │ └── cost: 1354.28 + │ └── cost: 1365.08 └── [] ├── best: (scan a,cols=(1-4)) - └── cost: 1094.81 + └── cost: 1105.61 # -------------------------------------------------- # With Ordinality @@ -690,14 +690,14 @@ memo (optimized, ~4KB, required=[presentation: y:2] [ordering: +7]) ├── G1: (ordinality G2) │ ├── [presentation: y:2] [ordering: +7] │ │ ├── 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 @@ -706,19 +706,19 @@ memo (optimized, ~5KB, required=[presentation: y:2] [ordering: +8]) ├── G1: (project G2 G3 y) │ ├── [presentation: y:2] [ordering: +8] │ │ ├── best: (sort G1) - │ │ └── cost: 1334.00 + │ │ └── cost: 1344.50 │ └── [] │ ├── 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) @@ -729,14 +729,14 @@ memo (optimized, ~6KB, required=[presentation: y:2] [ordering: +7]) ├── G1: (ordinality G2) │ ├── [presentation: y:2] [ordering: +7] │ │ ├── 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 @@ -745,17 +745,17 @@ memo (optimized, ~5KB, required=[presentation: y:2] [ordering: +2,+7]) ├── G1: (ordinality G2 ordering=+2) │ ├── [presentation: y:2] [ordering: +2,+7] │ │ ├── best: (ordinality G2="[ordering: +2]" ordering=+2) - │ │ └── cost: 1303.99 + │ │ └── cost: 1314.49 │ └── [] │ ├── best: (ordinality G2="[ordering: +2]" ordering=+2) - │ └── cost: 1303.99 + │ └── cost: 1314.49 └── G2: (scan a,cols=(2)) ├── [ordering: +2] │ ├── best: (sort G2) - │ └── cost: 1293.98 + │ └── cost: 1304.48 └── [] ├── 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 @@ -764,17 +764,17 @@ memo (optimized, ~5KB, required=[presentation: y:2] [ordering: +7]) ├── G1: (ordinality G2 ordering=+2) │ ├── [presentation: y:2] [ordering: +7] │ │ ├── best: (ordinality G2="[ordering: +2]" ordering=+2) - │ │ └── cost: 1303.99 + │ │ └── cost: 1314.49 │ └── [] │ ├── best: (ordinality G2="[ordering: +2]" ordering=+2) - │ └── cost: 1303.99 + │ └── cost: 1314.49 └── G2: (scan a,cols=(2)) ├── [ordering: +2] │ ├── best: (sort G2) - │ └── cost: 1293.98 + │ └── cost: 1304.48 └── [] ├── best: (scan a,cols=(2)) - └── cost: 1064.51 + └── cost: 1075.01 memo SELECT y FROM a WITH ORDINALITY ORDER BY ordinality DESC @@ -783,14 +783,14 @@ memo (optimized, ~4KB, required=[presentation: y:2] [ordering: -7]) ├── G1: (ordinality G2) │ ├── [presentation: y:2] [ordering: -7] │ │ ├── best: (sort G1) - │ │ └── cost: 1313.99 + │ │ └── cost: 1324.49 │ └── [] │ ├── 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 919f6414ee7f..11e30011bdfb 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:7]) │ │ └── 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:7]) ├── G1: (scalar-group-by G2 G3 cols=()) (scalar-group-by G4 G5 cols=()) │ └── [presentation: min:7] │ ├── 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.98 + │ │ └── cost: 1304.48 │ └── [] │ ├── 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: 1294.03 + │ └── cost: 1304.53 ├── 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: 1294.01 + │ │ └── cost: 1304.51 │ └── [] │ ├── 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:7]) │ │ └── 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:7]) ├── G1: (scalar-group-by G2 G3 cols=()) (scalar-group-by G4 G5 cols=()) │ └── [presentation: max:7] │ ├── 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.98 + │ │ └── cost: 1304.48 │ └── [] │ ├── 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: 1294.03 + │ └── cost: 1304.53 ├── 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: 1294.01 + │ │ └── cost: 1304.51 │ └── [] │ ├── 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:7]) ├── G1: (scalar-group-by G2 G3 cols=()) (scalar-group-by G4 G5 cols=()) │ └── [presentation: max:7] │ ├── 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.98 + │ │ └── cost: 1304.48 │ └── [] │ ├── 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: 1294.03 + │ └── cost: 1304.53 ├── 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: 1294.01 + │ │ └── cost: 1304.51 │ └── [] │ ├── 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:7]) ├── G1: (project G2 G3 array_agg) │ └── [presentation: array_agg:7] │ ├── 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:7]) ├── G1: (project G2 G3 sum) │ └── [presentation: sum:7] │ ├── 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:7]) ├── G1: (project G2 G3 sum) │ └── [presentation: sum:7] │ ├── 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,22 +1214,22 @@ memo (optimized, ~7KB, required=[presentation: array_agg:7]) ├── G1: (project G2 G3 array_agg) │ └── [presentation: array_agg:7] │ ├── 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 │ └── [] │ ├── best: (scan kuvw,cols=(2-4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G5: (aggregations G6) ├── G6: (array-agg G7) └── G7: (variable w) @@ -1242,66 +1242,66 @@ memo (optimized, ~12KB, required=[presentation: array_agg:7]) ├── G1: (project G2 G3 array_agg) │ └── [presentation: array_agg:7] │ ├── 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),+4) (group-by G4 G5 cols=(4),ordering=+4,+(2|3)) │ └── [] │ ├── 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]" G7) - │ │ └── cost: 1083.13 + │ │ └── cost: 1093.93 │ ├── [ordering: +(2|3),+4] │ │ ├── best: (select G8="[ordering: +2,+3,+4]" 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,+3,+4] │ │ ├── best: (scan kuvw@uvw,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ ├── [ordering: +2] │ │ ├── best: (scan kuvw@uvw,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ ├── [ordering: +4,+3] │ │ ├── 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,+3,+4] │ │ ├── best: (scan kuvw@uvw,cols=(1-4),constrained) - │ │ └── cost: 1073.21 + │ │ └── cost: 1084.01 │ ├── [ordering: +2] │ │ ├── best: (scan kuvw@uvw,cols=(1-4),constrained) - │ │ └── cost: 1073.21 + │ │ └── cost: 1084.01 │ ├── [ordering: +4,+2] │ │ ├── best: (sort G8) - │ │ └── cost: 1340.64 + │ │ └── cost: 1351.44 │ └── [] │ ├── best: (scan kuvw@uvw,cols=(1-4),constrained) - │ └── cost: 1073.21 + │ └── cost: 1084.01 ├── G9: (scan kuvw@vw,cols=(1-4),constrained) │ ├── [ordering: +3,+4] │ │ ├── best: (scan kuvw@vw,cols=(1-4),constrained) - │ │ └── cost: 1073.21 + │ │ └── cost: 1084.01 │ ├── [ordering: +3] │ │ ├── best: (scan kuvw@vw,cols=(1-4),constrained) - │ │ └── cost: 1073.21 + │ │ └── cost: 1084.01 │ ├── [ordering: +4,+2] │ │ ├── best: (sort G9) - │ │ └── cost: 1340.64 + │ │ └── cost: 1351.44 │ └── [] │ ├── 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) @@ -1315,66 +1315,66 @@ memo (optimized, ~12KB, required=[presentation: sum:7]) ├── G1: (project G2 G3 sum) │ └── [presentation: sum:7] │ ├── best: (project G2 G3 sum) - │ └── cost: 1083.65 + │ └── cost: 1094.45 ├── 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,+(2|3)) (group-by G4 G5 cols=(2,4),ordering=+4) │ └── [] │ ├── best: (group-by G4="[ordering: +(2|3),+4]" G5 cols=(2,4),ordering=+(2|3),+4) - │ └── cost: 1083.54 + │ └── cost: 1094.34 ├── G3: (projections) ├── G4: (select G6 G7) (select G8 G7) (select G9 G7) │ ├── [ordering: +(2|3),+4] │ │ ├── best: (select G8="[ordering: +2,+3,+4]" G7) - │ │ └── cost: 1083.13 + │ │ └── cost: 1093.93 │ ├── [ordering: +4,+(2|3)] │ │ ├── best: (sort G4) - │ │ └── cost: 1084.42 + │ │ └── cost: 1095.22 │ ├── [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,+3,+4] │ │ ├── best: (scan kuvw@uvw,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ ├── [ordering: +4,+3] │ │ ├── best: (scan kuvw@wvu,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,+3,+4] │ │ ├── best: (scan kuvw@uvw,cols=(1-4),constrained) - │ │ └── cost: 1073.21 + │ │ └── cost: 1084.01 │ ├── [ordering: +4,+2] │ │ ├── best: (sort G8) - │ │ └── cost: 1340.64 + │ │ └── cost: 1351.44 │ ├── [ordering: +4] │ │ ├── best: (sort G8) - │ │ └── cost: 1329.80 + │ │ └── cost: 1340.60 │ └── [] │ ├── best: (scan kuvw@uvw,cols=(1-4),constrained) - │ └── cost: 1073.21 + │ └── cost: 1084.01 ├── G9: (scan kuvw@vw,cols=(1-4),constrained) │ ├── [ordering: +3,+4] │ │ ├── best: (scan kuvw@vw,cols=(1-4),constrained) - │ │ └── cost: 1073.21 + │ │ └── cost: 1084.01 │ ├── [ordering: +4,+2] │ │ ├── best: (sort G9) - │ │ └── cost: 1340.64 + │ │ └── cost: 1351.44 │ ├── [ordering: +4] │ │ ├── best: (sort G9) - │ │ └── cost: 1329.80 + │ │ └── cost: 1340.60 │ └── [] │ ├── best: (scan kuvw@vw,cols=(1-4),constrained) - │ └── cost: 1073.21 + │ └── cost: 1084.01 ├── G10: (sum G12) ├── G11: (eq G13 G14) ├── G12: (variable k) @@ -1389,22 +1389,22 @@ memo (optimized, ~6KB, required=[presentation: array_agg:7]) ├── G1: (project G2 G3 array_agg) │ └── [presentation: array_agg:7] │ ├── best: (project G2 G3 array_agg) - │ └── cost: 1204.90 + │ └── cost: 1215.60 ├── 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: 1194.89 + │ └── cost: 1205.59 ├── 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] │ │ ├── best: (scan kuvw@uvw,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ ├── [ordering: -4 opt(2,3)] │ │ ├── best: (sort G4="[ordering: +2,+3]") - │ │ └── cost: 1144.72 + │ │ └── cost: 1155.42 │ └── [] │ ├── best: (scan kuvw,cols=(2-4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G5: (aggregations G6) ├── G6: (array-agg G7) └── G7: (variable w) @@ -1418,20 +1418,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. @@ -1442,17 +1442,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) @@ -1465,14 +1465,14 @@ memo (optimized, ~5KB, 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) @@ -1487,14 +1487,14 @@ memo (optimized, ~5KB, 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) @@ -1509,14 +1509,14 @@ memo (optimized, ~5KB, 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) @@ -1531,26 +1531,26 @@ memo (optimized, ~5KB, 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) @@ -1565,23 +1565,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) @@ -1596,26 +1596,26 @@ 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: 1218.11 + │ └── cost: 1228.81 ├── 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 │ ├── [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: (sort G2="[ordering: +2]") - │ │ └── cost: 1167.94 + │ │ └── cost: 1178.64 │ └── [] │ ├── best: (scan kuvw,cols=(2-4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G3: (aggregations G4) ├── G4: (first-agg G5) └── G5: (variable v) @@ -1627,23 +1627,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: 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: +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="[ordering: +4]") - │ │ └── cost: 1211.16 + │ │ └── cost: 1221.86 │ └── [] │ ├── best: (scan kuvw,cols=(2-4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G3: (aggregations G4 G5) ├── G4: (first-agg G6) ├── G5: (first-agg G7) @@ -1657,23 +1657,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: (sort G1) - │ │ └── cost: 1270.48 + │ │ └── cost: 1281.18 │ └── [] │ ├── 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: +4] │ │ ├── best: (scan kuvw@wvu,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ ├── [ordering: -2,+3 opt(4)] │ │ ├── best: (sort G2="[ordering: +4]") - │ │ └── cost: 1211.16 + │ │ └── cost: 1221.86 │ ├── [ordering: -4,-2,+3] │ │ ├── best: (sort G2) - │ │ └── cost: 1346.24 + │ │ └── cost: 1356.94 │ └── [] │ ├── best: (scan kuvw,cols=(2-4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G3: (aggregations G4 G5) ├── G4: (first-agg G6) ├── G5: (first-agg G7) @@ -1687,26 +1687,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) @@ -1721,65 +1721,65 @@ memo (optimized, ~27KB, required=[presentation: w:12] [ordering: +13,+1]) ├── G1: (project G2 G3 x) │ ├── [presentation: w:12] [ordering: +13,+1] │ │ ├── best: (sort G1) - │ │ └── cost: 1400.77 + │ │ └── cost: 1421.77 │ └── [] │ ├── 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) (right-join G9 G8 G10) (merge-join G8 G9 G11 left-join,+1,+7) (lookup-join G12 G11 kuvw@uvw,keyCols=[1 14],outCols=(1,7-9)) (lookup-join G13 G10 kuvw@vw,keyCols=[15],outCols=(1,7-9)) (merge-join G9 G8 G11 right-join,+7,+1) │ ├── [ordering: +1] │ │ ├── best: (merge-join G8="[ordering: +1]" G9="[ordering: +7 opt(8)]" G11 left-join,+1,+7) - │ │ └── cost: 1080.30 + │ │ └── cost: 1101.30 │ └── [] │ ├── best: (merge-join G8="[ordering: +1]" G9="[ordering: +7 opt(8)]" G11 left-join,+1,+7) - │ └── cost: 1080.30 + │ └── cost: 1101.30 ├── G5: (aggregations G14) ├── G6: (variable kuvw.w) ├── G7: (plus G15 G16) ├── 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 G17 G18) (scan kuvw@vw,cols=(7-9),constrained) │ ├── [ordering: +7 opt(8)] │ │ ├── best: (sort G9) - │ │ └── cost: 15.88 + │ │ └── cost: 26.58 │ └── [] │ ├── best: (scan kuvw@vw,cols=(7-9),constrained) - │ └── cost: 14.71 + │ └── cost: 25.41 ├── G10: (filters G19) ├── G11: (filters) ├── G12: (project G8 G20 x) │ ├── [ordering: +1] │ │ ├── best: (project G8="[ordering: +1]" G20 x) - │ │ └── cost: 1064.32 + │ │ └── cost: 1074.62 │ └── [] │ ├── best: (project G8 G20 x) - │ └── cost: 1064.32 + │ └── cost: 1074.62 ├── G13: (project G8 G20 x) │ ├── [ordering: +1] │ │ ├── best: (project G8="[ordering: +1]" G20 x) - │ │ └── cost: 1064.32 + │ │ └── cost: 1074.62 │ └── [] │ ├── best: (project G8 G20 x) - │ └── cost: 1064.32 + │ └── cost: 1074.62 ├── G14: (const-agg G6) ├── G15: (variable x) ├── G16: (const 1) ├── G17: (scan kuvw,cols=(7-9)) (scan kuvw@uvw,cols=(7-9)) (scan kuvw@wvu,cols=(7-9)) (scan kuvw@vw,cols=(7-9)) (scan kuvw@w,cols=(7-9)) │ ├── [ordering: +7] │ │ ├── best: (scan kuvw@uvw,cols=(7-9)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan kuvw,cols=(7-9)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G18: (filters G21) ├── G19: (eq G15 G22) ├── G20: (projections G16) @@ -1795,35 +1795,35 @@ memo (optimized, ~21KB, 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=(8)) (upsert-distinct-on G5 G6 cols=(8),ordering=+8 opt(12)) │ └── [] │ ├── best: (upsert-distinct-on G5 G6 cols=(8)) - │ └── cost: 2168.86 + │ └── cost: 2189.76 ├── G3: (unique-checks) ├── G4: (f-k-checks) ├── G5: (anti-join G7 G8 G9) (merge-join G7 G8 G10 anti-join,+8,+13) (lookup-join G7 G10 xyz,keyCols=[8],outCols=(8,9,12,13)) (lookup-join G7 G10 xyz@xy,keyCols=[8],outCols=(8,9,12,13)) │ ├── [ordering: +8 opt(12)] │ │ ├── best: (merge-join G7="[ordering: +8 opt(12)]" G8="[ordering: +13]" G10 anti-join,+8,+13) - │ │ └── cost: 2168.84 + │ │ └── cost: 2189.74 │ └── [] │ ├── best: (merge-join G7="[ordering: +8 opt(12)]" G8="[ordering: +13]" G10 anti-join,+8,+13) - │ └── cost: 2168.84 + │ └── cost: 2189.74 ├── G6: (aggregations G11 G12) ├── G7: (project G13 G14 v w) │ ├── [ordering: +8 opt(12)] │ │ ├── best: (project G13="[ordering: +8]" 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=(13)) (scan xyz@xy,cols=(13)) (scan xyz@zyx,cols=(13)) (scan xyz@yy,cols=(13)) │ ├── [ordering: +13] │ │ ├── best: (scan xyz@xy,cols=(13)) - │ │ └── cost: 1044.31 + │ │ └── cost: 1054.61 │ └── [] │ ├── best: (scan xyz@xy,cols=(13)) - │ └── cost: 1044.31 + │ └── cost: 1054.61 ├── G9: (filters G15) ├── G10: (filters) ├── G11: (first-agg G16) @@ -1831,10 +1831,10 @@ memo (optimized, ~21KB, required=[]) ├── G13: (scan kuvw,cols=(8,9)) (scan kuvw@uvw,cols=(8,9)) (scan kuvw@wvu,cols=(8,9)) (scan kuvw@vw,cols=(8,9)) (scan kuvw@w,cols=(8,9)) │ ├── [ordering: +8] │ │ ├── best: (scan kuvw@vw,cols=(8,9)) - │ │ └── cost: 1074.61 + │ │ └── cost: 1085.21 │ └── [] │ ├── best: (scan kuvw,cols=(8,9)) - │ └── cost: 1074.61 + │ └── cost: 1085.21 ├── G14: (projections G18) ├── G15: (eq G19 G20) ├── G16: (variable w) @@ -1851,46 +1851,46 @@ memo (optimized, ~22KB, 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) (right-join G8 G7 G9) (lookup-join G7 G10 xyz,keyCols=[8],outCols=(8,9,12-15)) (lookup-join G11 G10 xyz,keyCols=[13],outCols=(8,9,12-15)) (merge-join G8 G7 G10 right-join,+13,+8) │ └── [] │ ├── best: (merge-join G8="[ordering: +13]" G7="[ordering: +8 opt(12)]" G10 right-join,+13,+8) - │ └── cost: 2239.26 + │ └── cost: 2260.46 ├── G6: (projections G12) ├── G7: (ensure-upsert-distinct-on G13 G14 cols=(8)) (ensure-upsert-distinct-on G13 G14 cols=(8),ordering=+8 opt(12)) │ ├── [ordering: +8 opt(12)] │ │ ├── best: (ensure-upsert-distinct-on G13="[ordering: +8 opt(12)]" G14 cols=(8)) - │ │ └── cost: 1134.64 + │ │ └── cost: 1145.24 │ └── [] │ ├── best: (ensure-upsert-distinct-on G13="[ordering: +8 opt(12)]" G14 cols=(8),ordering=+8 opt(12)) - │ └── cost: 1134.64 + │ └── cost: 1145.24 ├── G8: (scan xyz,cols=(13-15)) (scan xyz@zyx,cols=(13-15)) │ ├── [ordering: +13] │ │ ├── best: (scan xyz,cols=(13-15)) - │ │ └── cost: 1074.61 + │ │ └── cost: 1085.21 │ └── [] │ ├── best: (scan xyz,cols=(13-15)) - │ └── cost: 1074.61 + │ └── cost: 1085.21 ├── G9: (filters G15) ├── G10: (filters) ├── G11: (lookup-join G7 G10 xyz@xy,keyCols=[8],outCols=(8,9,12-14)) │ └── [] │ ├── best: (lookup-join G7 G10 xyz@xy,keyCols=[8],outCols=(8,9,12-14)) - │ └── cost: 7184.65 + │ └── cost: 7195.25 ├── G12: (case G16 G17 G18) ├── G13: (project G19 G20 v w) │ ├── [ordering: +8 opt(12)] │ │ ├── best: (project G19="[ordering: +8]" G20 v w) - │ │ └── cost: 1094.62 + │ │ └── cost: 1105.22 │ └── [] │ ├── best: (project G19 G20 v w) - │ └── cost: 1094.62 + │ └── cost: 1105.22 ├── G14: (aggregations G21 G22) ├── G15: (eq G23 G24) ├── G16: (true) @@ -1899,10 +1899,10 @@ memo (optimized, ~22KB, required=[]) ├── G19: (scan kuvw,cols=(8,9)) (scan kuvw@uvw,cols=(8,9)) (scan kuvw@wvu,cols=(8,9)) (scan kuvw@vw,cols=(8,9)) (scan kuvw@w,cols=(8,9)) │ ├── [ordering: +8] │ │ ├── best: (scan kuvw@vw,cols=(8,9)) - │ │ └── cost: 1074.61 + │ │ └── cost: 1085.21 │ └── [] │ ├── best: (scan kuvw,cols=(8,9)) - │ └── cost: 1074.61 + │ └── cost: 1085.21 ├── G20: (projections G26) ├── G21: (first-agg G27) ├── G22: (first-agg G28) diff --git a/pkg/sql/opt/xform/testdata/rules/join b/pkg/sql/opt/xform/testdata/rules/join index 5e7cd5609075..18706790196e 100644 --- a/pkg/sql/opt/xform/testdata/rules/join +++ b/pkg/sql/opt/xform/testdata/rules/join @@ -174,51 +174,51 @@ memo (optimized, ~36KB, required=[presentation: a:1,b:2,c:3,s:7,t:8,u:9,x:12,y:1 ├── G1: (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,+7) (merge-join G3 G2 G10 inner-join,+7,+1) (lookup-join G3 G10 abc@ab,keyCols=[7],outCols=(1-3,7-9,12-14)) (merge-join G5 G6 G10 inner-join,+7,+12) (merge-join G6 G5 G10 inner-join,+12,+7) (lookup-join G6 G10 stu,keyCols=[12],outCols=(1-3,7-9,12-14)) (merge-join G8 G9 G10 inner-join,+7,+12) (lookup-join G8 G10 xyz@xy,keyCols=[7],outCols=(1-3,7-9,12-14)) (merge-join G9 G8 G10 inner-join,+12,+7) │ └── [presentation: a:1,b:2,c:3,s:7,t:8,u:9,x:12,y:13,z:14] │ ├── best: (merge-join G5="[ordering: +7]" G6="[ordering: +(1|12)]" G10 inner-join,+7,+12) - │ └── 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 G9 G5 G7) (merge-join G5 G9 G10 inner-join,+7,+12) (lookup-join G5 G10 xyz@xy,keyCols=[7],outCols=(7-9,12-14)) (merge-join G9 G5 G10 inner-join,+12,+7) (lookup-join G9 G10 stu,keyCols=[12],outCols=(7-9,12-14)) │ ├── [ordering: +(7|12)] │ │ ├── best: (merge-join G5="[ordering: +7]" G9="[ordering: +12]" G10 inner-join,+7,+12) - │ │ └── cost: 11909.33 + │ │ └── cost: 11930.63 │ └── [] │ ├── best: (merge-join G5="[ordering: +7]" G9="[ordering: +12]" G10 inner-join,+7,+12) - │ └── cost: 11909.33 + │ └── cost: 11930.63 ├── G4: (filters G11) ├── G5: (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 ├── G6: (inner-join G2 G9 G12) (inner-join G9 G2 G12) (merge-join G2 G9 G10 inner-join,+1,+12) (lookup-join G2 G10 xyz@xy,keyCols=[1],outCols=(1-3,12-14)) (merge-join G9 G2 G10 inner-join,+12,+1) (lookup-join G9 G10 abc@ab,keyCols=[12],outCols=(1-3,12-14)) │ ├── [ordering: +(1|12)] │ │ ├── best: (merge-join G2="[ordering: +1]" G9="[ordering: +12]" G10 inner-join,+1,+12) - │ │ └── cost: 2199.43 + │ │ └── cost: 2220.83 │ └── [] │ ├── best: (merge-join G2="[ordering: +1]" G9="[ordering: +12]" G10 inner-join,+1,+12) - │ └── 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,+7) (lookup-join G2 G10 stu,keyCols=[1],outCols=(1-3,7-9)) (merge-join G5 G2 G10 inner-join,+7,+1) (lookup-join G5 G10 abc@ab,keyCols=[7],outCols=(1-3,7-9)) │ ├── [ordering: +(1|7)] │ │ ├── best: (merge-join G2="[ordering: +1]" G5="[ordering: +7]" G10 inner-join,+1,+7) - │ │ └── cost: 11909.33 + │ │ └── cost: 11930.63 │ └── [] │ ├── best: (merge-join G2="[ordering: +1]" G5="[ordering: +7]" G10 inner-join,+1,+7) - │ └── cost: 11909.33 + │ └── cost: 11930.63 ├── G9: (scan xyz,cols=(12-14)) (scan xyz@xy,cols=(12-14)) (scan xyz@yz,cols=(12-14)) │ ├── [ordering: +12] │ │ ├── best: (scan xyz@xy,cols=(12-14)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan xyz,cols=(12-14)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G10: (filters) ├── G11: (eq G14 G15) ├── G12: (filters G16) @@ -302,74 +302,74 @@ memo (optimized, ~34KB, 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:9,pa1:13] [ordering: +1] │ │ ├── best: (project G2="[ordering: +(1|7|12)]" 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 G5 G4 G6) (merge-join G4 G5 G12 inner-join,+1,+12) (lookup-join G4 G12 parent1,keyCols=[1],outCols=(1-4,7-9,12,13)) (merge-join G7 G8 G12 inner-join,+1,+2,+7,+8) (merge-join G8 G7 G12 inner-join,+7,+8,+1,+2) (lookup-join G8 G12 grandchild1,keyCols=[7 8],outCols=(1-4,7-9,12,13)) (merge-join G10 G11 G12 inner-join,+7,+8,+1,+2) (merge-join G11 G10 G12 inner-join,+1,+2,+7,+8) (lookup-join G11 G12 child1,keyCols=[1 2],outCols=(1-4,7-9,12,13)) (merge-join G5 G4 G12 inner-join,+12,+1) │ ├── [ordering: +(1|7|12)] │ │ ├── best: (lookup-join G4="[ordering: +(1|7)]" G12 parent1,keyCols=[1],outCols=(1-4,7-9,12,13)) - │ │ └── cost: 2795.44 + │ │ └── cost: 2816.84 │ └── [] │ ├── best: (lookup-join G4 G12 parent1,keyCols=[1],outCols=(1-4,7-9,12,13)) - │ └── cost: 2795.44 + │ └── cost: 2816.84 ├── G3: (projections) ├── G4: (inner-join G7 G10 G9) (inner-join G10 G7 G9) (merge-join G7 G10 G12 inner-join,+1,+2,+7,+8) (lookup-join G7 G12 child1,keyCols=[1 2],outCols=(1-4,7-9)) (merge-join G10 G7 G12 inner-join,+7,+8,+1,+2) (lookup-join G10 G12 grandchild1,keyCols=[7 8],outCols=(1-4,7-9)) │ ├── [ordering: +(1|7)] │ │ ├── best: (merge-join G7="[ordering: +1,+2]" G10="[ordering: +7,+8]" G12 inner-join,+1,+2,+7,+8) - │ │ └── cost: 2190.43 + │ │ └── cost: 2211.83 │ └── [] │ ├── best: (merge-join G7="[ordering: +1,+2]" G10="[ordering: +7,+8]" G12 inner-join,+1,+2,+7,+8) - │ └── cost: 2190.43 + │ └── cost: 2211.83 ├── G5: (scan parent1,cols=(12,13)) │ ├── [ordering: +12] │ │ ├── best: (scan parent1,cols=(12,13)) - │ │ └── cost: 1054.41 + │ │ └── cost: 1064.81 │ └── [] │ ├── best: (scan parent1,cols=(12,13)) - │ └── 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,+7,+12) (lookup-join G10 G12 parent1,keyCols=[7],outCols=(7-9,12,13)) (merge-join G5 G10 G12 inner-join,+12,+7) (lookup-join G5 G12 child1,keyCols=[12],outCols=(7-9,12,13)) │ ├── [ordering: +(7|12),+8] │ │ ├── best: (sort G8) - │ │ └── cost: 2439.47 + │ │ └── cost: 2460.47 │ ├── [ordering: +(7|12)] │ │ ├── best: (merge-join G10="[ordering: +7]" G5="[ordering: +12]" G12 inner-join,+7,+12) - │ │ └── cost: 2159.03 + │ │ └── cost: 2180.03 │ └── [] │ ├── best: (merge-join G10="[ordering: +7]" G5="[ordering: +12]" G12 inner-join,+7,+12) - │ └── cost: 2159.03 + │ └── cost: 2180.03 ├── G9: (filters G15 G16) ├── G10: (scan child1,cols=(7-9)) │ ├── [ordering: +7,+8] │ │ ├── best: (scan child1,cols=(7-9)) - │ │ └── cost: 1074.61 + │ │ └── cost: 1085.21 │ ├── [ordering: +7] │ │ ├── best: (scan child1,cols=(7-9)) - │ │ └── cost: 1074.61 + │ │ └── cost: 1085.21 │ └── [] │ ├── best: (scan child1,cols=(7-9)) - │ └── 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,+12) (lookup-join G7 G12 parent1,keyCols=[1],outCols=(1-4,12,13)) (merge-join G5 G7 G12 inner-join,+12,+1) (lookup-join G5 G12 grandchild1,keyCols=[12],outCols=(1-4,12,13)) │ ├── [ordering: +(1|12),+2] │ │ ├── best: (sort G11) - │ │ └── cost: 2469.67 + │ │ └── cost: 2490.87 │ ├── [ordering: +(1|12)] │ │ ├── best: (merge-join G7="[ordering: +1]" G5="[ordering: +12]" G12 inner-join,+1,+12) - │ │ └── cost: 2179.23 + │ │ └── cost: 2200.43 │ └── [] │ ├── best: (merge-join G7="[ordering: +1]" G5="[ordering: +12]" G12 inner-join,+1,+12) - │ └── 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:7,t:8,u:9,x:12,y:1 ├── G1: (inner-join G2 G3 G4) (inner-join G3 G2 G4) │ └── [presentation: a:1,b:2,c:3,s:7,t:8,u:9,x:12,y:13,z:14,p:18,q:19,r:20,s:21,t:22] │ ├── best: (inner-join G3 G2 G4) - │ └── cost: 325035540.13 + │ └── cost: 325035583.13 ├── 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 G8 G7 G4) │ └── [] │ ├── best: (inner-join G8 G7 G4) - │ └── cost: 100035535.02 + │ └── cost: 100035567.32 ├── 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=(7-9)) (scan stu@uts,cols=(7-9)) │ └── [] │ ├── best: (scan stu,cols=(7-9)) - │ └── cost: 10614.61 + │ └── cost: 10625.21 ├── G8: (inner-join G10 G11 G4) (inner-join G11 G10 G4) │ └── [] │ ├── best: (inner-join G10 G11 G4) - │ └── cost: 12229.88 + │ └── cost: 12251.58 ├── G9: (eq G12 G13) ├── G10: (scan xyz,cols=(12-14)) (scan xyz@xy,cols=(12-14)) (scan xyz@yz,cols=(12-14)) │ └── [] │ ├── best: (scan xyz,cols=(12-14)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G11: (scan pqr,cols=(18-22)) │ └── [] │ ├── best: (scan pqr,cols=(18-22)) - │ └── cost: 1115.01 + │ └── cost: 1126.01 ├── G12: (variable a) └── G13: (const 1) @@ -436,53 +436,53 @@ memo (optimized, ~32KB, required=[presentation: s:1,t:2,u:3,a:6,b:7,c:8,x:12,y:1 ├── G1: (inner-join G2 G3 G4) (inner-join G3 G2 G4) (merge-join G2 G3 G5 inner-join,+3,+6) (merge-join G3 G2 G5 inner-join,+6,+3) (lookup-join G3 G5 stu@uts,keyCols=[6],outCols=(1-3,6-8,12-14,18-22)) │ └── [presentation: s:1,t:2,u:3,a:6,b:7,c:8,x:12,y:13,z:14,p:18,q:19,r:20,s:21,t:22] │ ├── best: (merge-join G2="[ordering: +3]" G3="[ordering: +(6|12|18)]" G5 inner-join,+3,+6) - │ └── 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 G7 G6 G8) (merge-join G6 G7 G5 inner-join,+6,+12) (merge-join G7 G6 G5 inner-join,+12,+6) (lookup-join G7 G5 abc@ab,keyCols=[12],outCols=(6-8,12-14,18-22)) │ ├── [ordering: +(6|12|18)] │ │ ├── best: (merge-join G6="[ordering: +6]" G7="[ordering: +(12|18)]" G5 inner-join,+6,+12) - │ │ └── cost: 3344.45 + │ │ └── cost: 3376.85 │ └── [] │ ├── best: (merge-join G6="[ordering: +6]" G7="[ordering: +(12|18)]" G5 inner-join,+6,+12) - │ └── cost: 3344.45 + │ └── cost: 3376.85 ├── G4: (filters G9) ├── G5: (filters) ├── G6: (scan abc,cols=(6-8)) (scan abc@ab,cols=(6-8)) (scan abc@bc,cols=(6-8)) │ ├── [ordering: +6] │ │ ├── best: (scan abc@ab,cols=(6-8)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan abc,cols=(6-8)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G7: (inner-join G10 G11 G12) (inner-join G11 G10 G12) (merge-join G10 G11 G5 inner-join,+12,+18) (lookup-join G10 G5 pqr,keyCols=[12],outCols=(12-14,18-22)) (merge-join G11 G10 G5 inner-join,+18,+12) (lookup-join G11 G5 xyz@xy,keyCols=[18],outCols=(12-14,18-22)) │ ├── [ordering: +(12|18)] │ │ ├── best: (merge-join G10="[ordering: +12]" G11="[ordering: +18]" G5 inner-join,+12,+18) - │ │ └── cost: 2229.73 + │ │ └── cost: 2251.43 │ └── [] │ ├── best: (merge-join G10="[ordering: +12]" G11="[ordering: +18]" G5 inner-join,+12,+18) - │ └── cost: 2229.73 + │ └── cost: 2251.43 ├── G8: (filters G13) ├── G9: (eq G14 G15) ├── G10: (scan xyz,cols=(12-14)) (scan xyz@xy,cols=(12-14)) (scan xyz@yz,cols=(12-14)) │ ├── [ordering: +12] │ │ ├── best: (scan xyz@xy,cols=(12-14)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan xyz,cols=(12-14)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G11: (scan pqr,cols=(18-22)) │ ├── [ordering: +18] │ │ ├── best: (scan pqr,cols=(18-22)) - │ │ └── cost: 1115.01 + │ │ └── cost: 1126.01 │ └── [] │ ├── best: (scan pqr,cols=(18-22)) - │ └── cost: 1115.01 + │ └── cost: 1126.01 ├── G12: (filters G16) ├── G13: (eq G15 G17) ├── G14: (variable u) @@ -530,11 +530,11 @@ memo (optimized, ~13KB, required=[presentation: a:1,b:2,c:3,v:7,s:8,t:9,u:10]) ├── G1: (inner-join-apply G2 G3 G4) │ └── [presentation: a:1,b:2,c:3,v:7,s:8,t:9,u:10] │ ├── best: (inner-join-apply G2 G3 G4) - │ └── cost: 1179.21 + │ └── cost: 1189.91 ├── 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 G6 G5 G7) (lookup-join G5 G8 stu,keyCols=[7],outCols=(7-10)) (merge-join G6 G5 G8 inner-join,+8,+7) │ └── [] │ ├── best: (lookup-join G5 G8 stu,keyCols=[7],outCols=(7-10)) @@ -550,10 +550,10 @@ memo (optimized, ~13KB, required=[presentation: a:1,b:2,c:3,v:7,s:8,t:9,u:10]) ├── G6: (scan stu,cols=(8-10)) (scan stu@uts,cols=(8-10)) │ ├── [ordering: +8] │ │ ├── best: (scan stu,cols=(8-10)) - │ │ └── cost: 10614.61 + │ │ └── cost: 10625.21 │ └── [] │ ├── best: (scan stu,cols=(8-10)) - │ └── cost: 10614.61 + │ └── cost: 10625.21 ├── G7: (filters G11) ├── G8: (filters) ├── G9: (eq G12 G13) @@ -1342,21 +1342,21 @@ memo (optimized, ~10KB, required=[presentation: a:1,b:2,c:3,x:7,y:8,z:9]) ├── G1: (inner-join G2 G3 G4) (inner-join G3 G2 G4) (merge-join G2 G3 G5 inner-join,+1,+9) (lookup-join G3 G5 abc@ab,keyCols=[9],outCols=(1-3,7-9)) │ └── [presentation: a:1,b:2,c:3,x:7,y:8,z:9] │ ├── best: (inner-join G2 G3 G4) - │ └── cost: 2209.48 + │ └── cost: 2230.88 ├── 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=(7-9)) (scan xyz@xy,cols=(7-9)) (scan xyz@yz,cols=(7-9)) │ ├── [ordering: +9] │ │ ├── best: (sort G3) - │ │ └── cost: 1334.18 + │ │ └── cost: 1344.88 │ └── [] │ ├── best: (scan xyz,cols=(7-9)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G4: (filters G6) ├── G5: (filters) ├── G6: (eq G7 G8) @@ -1370,21 +1370,21 @@ memo (optimized, ~9KB, required=[presentation: a:1,b:2,c:3,x:7,y:8,z:9]) ├── G1: (full-join G2 G3 G4) (full-join G3 G2 G4) (merge-join G2 G3 G5 full-join,+1,+9) │ └── [presentation: a:1,b:2,c:3,x:7,y:8,z:9] │ ├── best: (full-join G2 G3 G4) - │ └── cost: 2209.58 + │ └── cost: 2230.98 ├── 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=(7-9)) (scan xyz@xy,cols=(7-9)) (scan xyz@yz,cols=(7-9)) │ ├── [ordering: +9] │ │ ├── best: (sort G3) - │ │ └── cost: 1334.18 + │ │ └── cost: 1344.88 │ └── [] │ ├── best: (scan xyz,cols=(7-9)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G4: (filters G6) ├── G5: (filters) ├── G6: (eq G7 G8) @@ -1456,15 +1456,15 @@ memo (optimized, ~10KB, required=[presentation: a:1,b:2,c:3,x:7,y:8,z:9]) ├── G1: (inner-join G2 G3 G4) (lookup-join G2 G5 xyz@xy,keyCols=[1],outCols=(1-3,7-9)) │ └── [presentation: a:1,b:2,c:3,x:7,y:8,z:9] │ ├── best: (lookup-join G2 G5 xyz@xy,keyCols=[1],outCols=(1-3,7-9)) - │ └── 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=(7-9)) (scan xyz@xy,cols=(7-9)) (scan xyz@yz,cols=(7-9)) │ └── [] │ ├── best: (scan xyz,cols=(7-9)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G4: (filters G6) ├── G5: (filters) ├── G6: (eq G7 G8) @@ -1539,21 +1539,21 @@ memo (optimized, ~9KB, required=[presentation: a:1,b:2,c:3,x:7,y:8,z:9]) ├── G1: (left-join G2 G3 G4) (right-join G3 G2 G4) (merge-join G2 G3 G5 left-join,+1,+9) │ └── [presentation: a:1,b:2,c:3,x:7,y:8,z:9] │ ├── best: (left-join G2 G3 G4) - │ └── cost: 2209.58 + │ └── cost: 2230.98 ├── 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=(7-9)) (scan xyz@xy,cols=(7-9)) (scan xyz@yz,cols=(7-9)) │ ├── [ordering: +9] │ │ ├── best: (sort G3) - │ │ └── cost: 1334.18 + │ │ └── cost: 1344.88 │ └── [] │ ├── best: (scan xyz,cols=(7-9)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G4: (filters G6) ├── G5: (filters) ├── G6: (eq G7 G8) @@ -1586,21 +1586,21 @@ memo (optimized, ~10KB, required=[presentation: a:1,b:2,c:3,x:7,y:8,z:9]) ├── G1: (left-join G2 G3 G4) (right-join G3 G2 G4) (lookup-join G2 G5 abc@ab,keyCols=[9],outCols=(1-3,7-9)) (merge-join G3 G2 G5 right-join,+1,+9) │ └── [presentation: a:1,b:2,c:3,x:7,y:8,z:9] │ ├── best: (left-join G2 G3 G4) - │ └── cost: 2209.58 + │ └── cost: 2230.98 ├── G2: (scan xyz,cols=(7-9)) (scan xyz@xy,cols=(7-9)) (scan xyz@yz,cols=(7-9)) │ ├── [ordering: +9] │ │ ├── best: (sort G2) - │ │ └── cost: 1334.18 + │ │ └── cost: 1344.88 │ └── [] │ ├── best: (scan xyz,cols=(7-9)) - │ └── 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) @@ -1713,13 +1713,13 @@ semi-join (lookup t.public.def) ├── key columns: [1 3] = [7 8] ├── 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-6) @@ -1736,13 +1736,13 @@ semi-join (lookup t.public.def) ├── key columns: [1 3] = [7 8] ├── 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-6) @@ -1870,21 +1870,21 @@ memo (optimized, ~12KB, required=[presentation: a:1,b:2,c:3,x:7,y:8,z:9]) ├── G1: (inner-join G2 G3 G4) (inner-join G3 G2 G4) (merge-join G2 G3 G5 inner-join,+1,+7) (lookup-join G2 G5 xyz@xy,keyCols=[1],outCols=(1-3,7-9)) (merge-join G3 G2 G5 inner-join,+7,+1) (lookup-join G3 G5 abc@ab,keyCols=[7],outCols=(1-3,7-9)) │ └── [presentation: a:1,b:2,c:3,x:7,y:8,z:9] │ ├── best: (merge-join G2="[ordering: +1]" G3="[ordering: +7]" G5 inner-join,+1,+7) - │ └── 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=(7-9)) (scan xyz@xy,cols=(7-9)) (scan xyz@yz,cols=(7-9)) │ ├── [ordering: +7] │ │ ├── best: (scan xyz@xy,cols=(7-9)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── best: (scan xyz,cols=(7-9)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G4: (filters G6) ├── G5: (filters) ├── G6: (eq G7 G8) @@ -1899,15 +1899,15 @@ memo (optimized, ~9KB, required=[presentation: a:1,b:2,c:3,x:7,y:8,z:9]) ├── G1: (inner-join G2 G3 G4) │ └── [presentation: a:1,b:2,c:3,x:7,y:8,z:9] │ ├── best: (inner-join G2 G3 G4) - │ └── cost: 1226.33 + │ └── cost: 1247.73 ├── 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=(7-9)) (scan xyz@xy,cols=(7-9)) (scan xyz@yz,cols=(7-9)) │ └── [] │ ├── best: (scan xyz,cols=(7-9)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G4: (filters G5) ├── G5: (eq G6 G7) ├── G6: (variable a) @@ -1950,20 +1950,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:7!null y:8!null z:9 + ├── key columns: [1 2] = [7 8] ├── fd: ()-->(2,8), (1)==(7), (7)==(1), (2)==(8), (8)==(2) - ├── scan xyz@yz - │ ├── columns: x:7 y:8!null z:9 - │ ├── constraint: /8/9/10: [/1 - /1] - │ └── fd: ()-->(8) ├── scan abc@bc │ ├── columns: a:1 b:2!null c:3 │ ├── constraint: /2/3/4: [/1 - /1] │ └── fd: ()-->(2) └── filters - ├── a:1 = x:7 [outer=(1,7), constraints=(/1: (/NULL - ]; /7: (/NULL - ]), fd=(1)==(7), (7)==(1)] - └── b:2 = y:8 [outer=(2,8), constraints=(/2: (/NULL - ]; /8: (/NULL - ]), fd=(2)==(8), (8)==(2)] + └── y:8 = 1 [outer=(8), constraints=(/8: [/1 - /1]; tight), fd=()-->(8)] # Verify case where we generate multiple merge-joins. memo @@ -1973,27 +1969,27 @@ memo (optimized, ~15KB, required=[presentation: s:1,t:2,u:3,s:6,t:7,u:8]) ├── G1: (inner-join G2 G3 G4) (inner-join G3 G2 G4) (merge-join G2 G3 G5 inner-join,+1,+2,+3,+6,+7,+8) (merge-join G2 G3 G5 inner-join,+3,+2,+1,+8,+7,+6) (lookup-join G2 G5 stu [as=r],keyCols=[1 2 3],outCols=(1-3,6-8)) (lookup-join G2 G5 stu@uts [as=r],keyCols=[3 2 1],outCols=(1-3,6-8)) (merge-join G3 G2 G5 inner-join,+6,+7,+8,+1,+2,+3) (merge-join G3 G2 G5 inner-join,+8,+7,+6,+3,+2,+1) (lookup-join G3 G5 stu [as=l],keyCols=[6 7 8],outCols=(1-3,6-8)) (lookup-join G3 G5 stu@uts [as=l],keyCols=[8 7 6],outCols=(1-3,6-8)) │ └── [presentation: s:1,t:2,u:3,s:6,t:7,u:8] │ ├── best: (merge-join G2="[ordering: +1,+2,+3]" G3="[ordering: +6,+7,+8]" G5 inner-join,+1,+2,+3,+6,+7,+8) - │ └── 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=(6-8)) (scan stu@uts [as=r],cols=(6-8)) │ ├── [ordering: +6,+7,+8] │ │ ├── best: (scan stu [as=r],cols=(6-8)) - │ │ └── cost: 10614.61 + │ │ └── cost: 10625.21 │ ├── [ordering: +8,+7,+6] │ │ ├── best: (scan stu@uts [as=r],cols=(6-8)) - │ │ └── cost: 10614.61 + │ │ └── cost: 10625.21 │ └── [] │ ├── best: (scan stu [as=r],cols=(6-8)) - │ └── cost: 10614.61 + │ └── cost: 10625.21 ├── G4: (filters G6 G7 G8) ├── G5: (filters) ├── G6: (eq G9 G10) @@ -2180,29 +2176,29 @@ memo (optimized, ~13KB, required=[presentation: a:1,b:2,c:3,x:7,y:8,z:9]) ├── G1: (inner-join G2 G3 G4) (inner-join G3 G2 G4) │ └── [presentation: a:1,b:2,c:3,x:7,y:8,z:9] │ ├── 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=(7-9)) (scan xyz@xy,cols=(7-9)) (scan xyz@yz,cols=(7-9)) │ └── [] │ ├── best: (scan xyz,cols=(7-9)) - │ └── 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) @@ -2218,15 +2214,15 @@ memo (optimized, ~10KB, required=[presentation: a:1,b:2,c:3,k:7]) ├── G1: (inner-join G2 G3 G4) (inner-join G3 G2 G4) │ └── [presentation: a:1,b:2,c:3,k:7] │ ├── 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=(7)) │ └── [] │ ├── best: (scan kfloat,cols=(7)) - │ └── cost: 1034.21 + │ └── cost: 1044.41 ├── G4: (filters G5) ├── G5: (eq G6 G7) ├── G6: (variable a) @@ -2704,15 +2700,15 @@ memo (optimized, ~8KB, required=[presentation: a:6,b:7,n:2,m:1]) ├── G1: (inner-join G2 G3 G4) │ └── [presentation: a:6,b:7,n:2,m:1] │ ├── best: (inner-join G2 G3 G4) - │ └── cost: 1108.29 + │ └── cost: 1129.29 ├── G2: (scan small,cols=(1,2)) │ └── [] │ ├── best: (scan small,cols=(1,2)) - │ └── cost: 25.01 + │ └── cost: 35.51 ├── G3: (scan abcd,cols=(6,7)) (scan abcd@secondary,cols=(6,7)) │ └── [] │ ├── best: (scan abcd@secondary,cols=(6,7)) - │ └── cost: 1064.51 + │ └── cost: 1075.01 ├── G4: (filters G5) ├── G5: (eq G6 G7) ├── G6: (variable a) @@ -4043,14 +4039,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] = [7] - ├── 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 @@ -4058,14 +4054,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] = [7] - ├── cost: 245.216 + ├── cost: 255.716 ├── scan small │ ├── columns: m:1 n:2 - │ └── cost: 25.01 + │ └── cost: 35.51 └── filters (true) exec-ddl @@ -4282,43 +4278,43 @@ memo (optimized, ~28KB, required=[presentation: name:16,popn_per_sqkm:22]) ├── G1: (project G2 G3 name) │ └── [presentation: name:16,popn_per_sqkm:22] │ ├── best: (project G2 G3 name) - │ └── cost: 7322.84 + │ └── cost: 7333.54 ├── G2: (group-by G4 G5 cols=(16,17)) │ └── [] │ ├── best: (group-by G4 G5 cols=(16,17)) - │ └── cost: 7322.79 + │ └── cost: 7333.49 ├── G3: (projections G6) ├── G4: (inner-join G7 G8 G9) (inner-join G8 G7 G9) (lookup-join G10 G11 nyc_neighborhoods [as=n],keyCols=[23],outCols=(3,9,10,15-17)) (lookup-join G12 G9 nyc_census_blocks [as=c],keyCols=[30],outCols=(3,9,10,15-17)) │ └── [] │ ├── best: (lookup-join G12 G9 nyc_census_blocks [as=c],keyCols=[30],outCols=(3,9,10,15-17)) - │ └── cost: 7316.67 + │ └── cost: 7327.37 ├── G5: (aggregations G13) ├── G6: (div G14 G15) ├── 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 G16 G17) │ └── [] │ ├── best: (select G16 G17) - │ └── cost: 154.05 + │ └── cost: 164.75 ├── G9: (filters G18 G19) ├── G10: (inverted-join G7 G20 nyc_neighborhoods@nyc_neighborhoods_geo_idx [as=n]) │ └── [] │ ├── best: (inverted-join G7 G20 nyc_neighborhoods@nyc_neighborhoods_geo_idx [as=n]) - │ └── cost: 921822.83 + │ └── cost: 921834.13 ├── G11: (filters G18 G19 G21) ├── G12: (inverted-join G8 G20 nyc_census_blocks@nyc_census_blocks_geo_idx [as=c]) │ └── [] │ ├── best: (inverted-join G8 G20 nyc_census_blocks@nyc_census_blocks_geo_idx [as=c]) - │ └── cost: 1776.86 + │ └── cost: 1787.56 ├── G13: (sum G22) ├── G14: (variable sum) ├── G15: (div G23 G24) ├── G16: (scan nyc_neighborhoods [as=n],cols=(15-17)) │ └── [] │ ├── best: (scan nyc_neighborhoods [as=n],cols=(15-17)) - │ └── cost: 152.74 + │ └── cost: 163.44 ├── G17: (filters G21) ├── G18: (function G25 st_intersects) ├── G19: (eq G26 G27) diff --git a/pkg/sql/opt/xform/testdata/rules/join_order b/pkg/sql/opt/xform/testdata/rules/join_order index 3efdffa8f74f..b0494fe5bad9 100644 --- a/pkg/sql/opt/xform/testdata/rules/join_order +++ b/pkg/sql/opt/xform/testdata/rules/join_order @@ -316,27 +316,27 @@ memo (optimized, ~24KB, required=[presentation: b:1,x:2,c:5,y:6,a:9,b:10,c:11,d: ├── G1: (inner-join G2 G3 G4) (merge-join G2 G3 G5 inner-join,+1,+10) │ └── [presentation: b:1,x:2,c:5,y:6,a:9,b:10,c:11,d:12] │ ├── best: (merge-join G2="[ordering: +1]" G3 G5 inner-join,+1,+10) - │ └── 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,+5,+11) (lookup-join G9 G8 abc,keyCols=[15],outCols=(5,6,9-12)) │ └── [] │ ├── best: (merge-join G6="[ordering: +5]" G7 G5 inner-join,+5,+11) - │ └── cost: 1069.53 + │ └── cost: 1079.93 ├── G4: (filters G10) ├── G5: (filters) ├── G6: (scan cy,cols=(5,6)) │ ├── [ordering: +5] │ │ ├── best: (scan cy,cols=(5,6)) - │ │ └── cost: 1054.41 + │ │ └── cost: 1064.81 │ └── [] │ ├── best: (scan cy,cols=(5,6)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G7: (select G11 G12) (scan abc,cols=(9-12),constrained) │ └── [] │ ├── best: (scan abc,cols=(9-12),constrained) @@ -345,12 +345,12 @@ memo (optimized, ~24KB, required=[presentation: b:1,x:2,c:5,y:6,a:9,b:10,c:11,d: ├── 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=(9-12)) │ └── [] │ ├── best: (scan abc,cols=(9-12)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── G12: (filters G17) ├── G13: (eq G18 G19) ├── G14: (projections G20) @@ -373,10 +373,10 @@ memo (optimized, ~39KB, required=[presentation: b:1,x:2,c:5,y:6,a:9,b:10,c:11,d: ├── 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 G9 G5 G7) (merge-join G5 G9 G8 inner-join,+5,+11) (lookup-join G10 G7 abc,keyCols=[15],outCols=(5,6,9-12)) (merge-join G9 G5 G8 inner-join,+11,+5) (lookup-join G9 G8 cy,keyCols=[11],outCols=(5,6,9-12)) │ └── [] │ ├── best: (lookup-join G9 G8 cy,keyCols=[11],outCols=(5,6,9-12)) @@ -385,10 +385,10 @@ memo (optimized, ~39KB, required=[presentation: b:1,x:2,c:5,y:6,a:9,b:10,c:11,d: ├── G5: (scan cy,cols=(5,6)) │ ├── [ordering: +5] │ │ ├── best: (scan cy,cols=(5,6)) - │ │ └── cost: 1054.41 + │ │ └── cost: 1064.81 │ └── [] │ ├── best: (scan cy,cols=(5,6)) - │ └── 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,+10) (lookup-join G12 G4 abc,keyCols=[16],outCols=(1,2,9-12)) (merge-join G9 G2 G8 inner-join,+10,+1) (lookup-join G9 G8 bx,keyCols=[10],outCols=(1,2,9-12)) │ └── [] │ ├── best: (lookup-join G9 G8 bx,keyCols=[10],outCols=(1,2,9-12)) @@ -402,17 +402,17 @@ memo (optimized, ~39KB, required=[presentation: b:1,x:2,c:5,y:6,a:9,b:10,c:11,d: ├── G10: (project G5 G16 c y) │ └── [] │ ├── best: (project G5 G16 c y) - │ └── cost: 1074.42 + │ └── cost: 1084.82 ├── G11: (eq G17 G18) ├── G12: (project G2 G16 b x) │ └── [] │ ├── best: (project G2 G16 b x) - │ └── cost: 1074.42 + │ └── cost: 1084.82 ├── G13: (eq G19 G20) ├── G14: (scan abc,cols=(9-12)) │ └── [] │ ├── best: (scan abc,cols=(9-12)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── G15: (filters G21) ├── G16: (projections G22) ├── G17: (variable abc.b) @@ -468,7 +468,7 @@ inner-join (cross) ├── columns: a:1(int!null) b:2(int) c:3(int) d:4(int) b:7(int!null) x:8(int) c:11(int!null) y:12(int) d:15(int!null) z:16(int) ├── multiplicity: left-rows(zero-or-one), right-rows(zero-or-more) ├── stats: [rows=1e+09] - ├── cost: 32525716.2 + ├── cost: 32525747.4 ├── key: (7,11,15) ├── fd: ()-->(1-4), (7)-->(8), (11)-->(12), (15)-->(16) ├── prune: (2-4,7,8,11,12,15,16) @@ -476,7 +476,7 @@ inner-join (cross) ├── inner-join (cross) │ ├── columns: t.public.bx.b:7(int!null) t.public.bx.x:8(int) t.public.cy.c:11(int!null) t.public.cy.y:12(int) t.public.dz.d:15(int!null) t.public.dz.z:16(int) │ ├── stats: [rows=1e+09] - │ ├── cost: 10025711 + │ ├── cost: 10025742.2 │ ├── key: (7,11,15) │ ├── fd: (7)-->(8), (11)-->(12), (15)-->(16) │ ├── prune: (7,8,11,12,15,16) @@ -484,7 +484,7 @@ inner-join (cross) │ ├── inner-join (cross) │ │ ├── columns: t.public.cy.c:11(int!null) t.public.cy.y:12(int) t.public.dz.d:15(int!null) t.public.dz.z:16(int) │ │ ├── stats: [rows=1000000] - │ │ ├── cost: 12138.9763 + │ │ ├── cost: 12159.7763 │ │ ├── key: (11,15) │ │ ├── fd: (11)-->(12), (15)-->(16) │ │ ├── prune: (11,12,15,16) @@ -492,7 +492,7 @@ inner-join (cross) │ │ ├── scan t.public.cy │ │ │ ├── columns: t.public.cy.c:11(int!null) t.public.cy.y:12(int) │ │ │ ├── stats: [rows=1000] - │ │ │ ├── cost: 1054.41 + │ │ │ ├── cost: 1064.81 │ │ │ ├── key: (11) │ │ │ ├── fd: (11)-->(12) │ │ │ ├── prune: (11,12) @@ -501,7 +501,7 @@ inner-join (cross) │ │ ├── scan t.public.dz │ │ │ ├── columns: t.public.dz.d:15(int!null) t.public.dz.z:16(int) │ │ │ ├── stats: [rows=1000] - │ │ │ ├── cost: 1054.41 + │ │ │ ├── cost: 1064.81 │ │ │ ├── key: (15) │ │ │ ├── fd: (15)-->(16) │ │ │ ├── prune: (15,16) @@ -511,7 +511,7 @@ inner-join (cross) │ ├── scan t.public.bx │ │ ├── columns: t.public.bx.b:7(int!null) t.public.bx.x:8(int) │ │ ├── stats: [rows=1000] - │ │ ├── cost: 1054.41 + │ │ ├── cost: 1064.81 │ │ ├── key: (7) │ │ ├── fd: (7)-->(8) │ │ ├── prune: (7,8) @@ -539,53 +539,53 @@ memo (optimized, ~24KB, required=[presentation: b:1,x:2,c:5,y:6,d:9,z:10,a:13,b: ├── G1: (inner-join G2 G3 G4) (merge-join G2 G3 G5 inner-join,+2,+6) │ └── [presentation: b:1,x:2,c:5,y:6,d:9,z:10,a:13,b:14,c:15,d:16] │ ├── best: (inner-join G2 G3 G4) - │ └── cost: 5595.32 + │ └── cost: 5637.32 ├── G2: (scan bx,cols=(1,2)) │ ├── [ordering: +2] │ │ ├── best: (sort G2) - │ │ └── cost: 1293.88 + │ │ └── cost: 1304.28 │ └── [] │ ├── 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,+6,+10) │ ├── [ordering: +(6|10|13)] │ │ ├── best: (merge-join G6="[ordering: +6]" G7="[ordering: +(10|13)]" G5 inner-join,+6,+10) - │ │ └── cost: 3830.40 + │ │ └── cost: 3862.00 │ └── [] │ ├── best: (inner-join G6 G7 G8) - │ └── cost: 3371.67 + │ └── cost: 3403.27 ├── G4: (filters G9) ├── G5: (filters) ├── G6: (scan cy,cols=(5,6)) │ ├── [ordering: +6] │ │ ├── best: (sort G6) - │ │ └── cost: 1293.88 + │ │ └── cost: 1304.28 │ └── [] │ ├── best: (scan cy,cols=(5,6)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G7: (inner-join G10 G11 G12) (merge-join G10 G11 G5 inner-join,+10,+13) (lookup-join G10 G5 abc,keyCols=[10],outCols=(9,10,13-16)) │ ├── [ordering: +(10|13)] │ │ ├── best: (merge-join G10="[ordering: +10]" G11="[ordering: +13]" G5 inner-join,+10,+13) - │ │ └── cost: 2418.60 + │ │ └── cost: 2439.80 │ └── [] │ ├── best: (inner-join G10 G11 G12) - │ └── cost: 2189.28 + │ └── cost: 2210.48 ├── G8: (filters G13) ├── G9: (eq G14 G15) ├── G10: (scan dz,cols=(9,10)) │ ├── [ordering: +10] │ │ ├── best: (sort G10) - │ │ └── cost: 1293.88 + │ │ └── cost: 1304.28 │ └── [] │ ├── best: (scan dz,cols=(9,10)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G11: (scan abc,cols=(13-16)) │ ├── [ordering: +13] │ │ ├── best: (scan abc,cols=(13-16)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ └── [] │ ├── best: (scan abc,cols=(13-16)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── G12: (filters G16) ├── G13: (eq G15 G17) ├── G14: (variable x) @@ -605,108 +605,108 @@ memo (optimized, ~55KB, required=[presentation: b:1,x:2,c:5,y:6,d:9,z:10,a:13,b: ├── G1: (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 G3 G2 G19 inner-join,+6,+2) (merge-join G6 G5 G19 inner-join,+10,+6) (merge-join G9 G8 G19 inner-join,+10,+6) (merge-join G11 G10 G19 inner-join,+13,+10) (merge-join G14 G13 G19 inner-join,+13,+10) (merge-join G16 G15 G19 inner-join,+13,+10) (lookup-join G17 G19 abc,keyCols=[10],outCols=(1,2,5,6,9,10,13-16)) (merge-join G18 G17 G19 inner-join,+13,+10) │ └── [presentation: b:1,x:2,c:5,y:6,d:9,z:10,a:13,b:14,c:15,d:16] │ ├── best: (inner-join G3 G2 G4) - │ └── cost: 5536.55 + │ └── cost: 5578.55 ├── G2: (scan bx,cols=(1,2)) │ ├── [ordering: +2] │ │ ├── best: (sort G2) - │ │ └── cost: 1293.88 + │ │ └── cost: 1304.28 │ └── [] │ ├── best: (scan bx,cols=(1,2)) - │ └── cost: 1054.41 + │ └── cost: 1064.81 ├── G3: (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 G9 G5 G19 inner-join,+10,+6) (merge-join G14 G10 G19 inner-join,+13,+10) (lookup-join G15 G19 abc,keyCols=[10],outCols=(5,6,9,10,13-16)) (merge-join G18 G15 G19 inner-join,+13,+10) │ ├── [ordering: +(6|10|13)] │ │ ├── best: (merge-join G9="[ordering: +(10|13)]" G5="[ordering: +6]" G19 inner-join,+10,+6) - │ │ └── cost: 3830.40 + │ │ └── cost: 3862.00 │ └── [] │ ├── best: (inner-join G5 G9 G7) - │ └── cost: 3371.67 + │ └── cost: 3403.27 ├── G4: (filters G20) ├── G5: (scan cy,cols=(5,6)) │ ├── [ordering: +6] │ │ ├── best: (sort G5) - │ │ └── cost: 1293.88 + │ │ └── cost: 1304.28 │ └── [] │ ├── best: (scan cy,cols=(5,6)) - │ └── 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 G9 G2 G19 inner-join,+10,+2) (merge-join G16 G10 G19 inner-join,+13,+10) (lookup-join G13 G19 abc,keyCols=[10],outCols=(1,2,9,10,13-16)) (merge-join G18 G13 G19 inner-join,+13,+10) │ ├── [ordering: +(2|10|13)] │ │ ├── best: (merge-join G9="[ordering: +(10|13)]" G2="[ordering: +2]" G19 inner-join,+10,+2) - │ │ └── cost: 3830.40 + │ │ └── cost: 3862.00 │ └── [] │ ├── best: (inner-join G2 G9 G21) - │ └── cost: 3371.67 + │ └── cost: 3403.27 ├── G7: (filters G22) ├── G8: (inner-join G2 G5 G4) (inner-join G5 G2 G4) │ ├── [ordering: +(2|6)] │ │ ├── best: (sort G8) - │ │ └── cost: 5438.94 + │ │ └── cost: 5459.74 │ └── [] │ ├── best: (inner-join G2 G5 G4) - │ └── cost: 2236.99 + │ └── cost: 2257.79 ├── G9: (inner-join G10 G18 G12) (inner-join G18 G10 G12) (lookup-join G10 G19 abc,keyCols=[10],outCols=(9,10,13-16)) (merge-join G18 G10 G19 inner-join,+13,+10) │ ├── [ordering: +(10|13)] │ │ ├── best: (merge-join G18="[ordering: +13]" G10="[ordering: +10]" G19 inner-join,+13,+10) - │ │ └── cost: 2418.60 + │ │ └── cost: 2439.80 │ └── [] │ ├── best: (inner-join G10 G18 G12) - │ └── cost: 2189.28 + │ └── cost: 2210.48 ├── G10: (scan dz,cols=(9,10)) │ ├── [ordering: +10] │ │ ├── best: (sort G10) - │ │ └── cost: 1293.88 + │ │ └── cost: 1304.28 │ └── [] │ ├── best: (scan dz,cols=(9,10)) - │ └── 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) (merge-join G14 G2 G19 inner-join,+6,+2) (merge-join G16 G5 G19 inner-join,+2,+6) (lookup-join G8 G19 abc,keyCols=[6],outCols=(1,2,5,6,13-16)) (merge-join G18 G8 G19 inner-join,+13,+6) │ ├── [ordering: +(2|6|13)] │ │ ├── best: (merge-join G14="[ordering: +(6|13)]" G2="[ordering: +2]" G19 inner-join,+6,+2) - │ │ └── cost: 3830.40 + │ │ └── cost: 3862.00 │ └── [] │ ├── best: (inner-join G2 G14 G4) - │ └── cost: 3371.67 + │ └── cost: 3403.27 ├── G12: (filters G24) ├── G13: (inner-join G2 G10 G21) (inner-join G10 G2 G21) │ ├── [ordering: +(2|10)] │ │ ├── best: (sort G13) - │ │ └── cost: 5438.94 + │ │ └── cost: 5459.74 │ └── [] │ ├── best: (inner-join G2 G10 G21) - │ └── cost: 2236.99 + │ └── cost: 2257.79 ├── G14: (inner-join G5 G18 G23) (inner-join G18 G5 G23) (lookup-join G5 G19 abc,keyCols=[6],outCols=(5,6,13-16)) (merge-join G18 G5 G19 inner-join,+13,+6) │ ├── [ordering: +(6|13)] │ │ ├── best: (merge-join G18="[ordering: +13]" G5="[ordering: +6]" G19 inner-join,+13,+6) - │ │ └── cost: 2418.60 + │ │ └── cost: 2439.80 │ └── [] │ ├── best: (inner-join G5 G18 G23) - │ └── cost: 2189.28 + │ └── cost: 2210.48 ├── G15: (inner-join G5 G10 G7) (inner-join G10 G5 G7) │ ├── [ordering: +(6|10)] │ │ ├── best: (sort G15) - │ │ └── cost: 5438.94 + │ │ └── cost: 5459.74 │ └── [] │ ├── best: (inner-join G5 G10 G7) - │ └── cost: 2236.99 + │ └── cost: 2257.79 ├── G16: (inner-join G2 G18 G25) (inner-join G18 G2 G25) (lookup-join G2 G19 abc,keyCols=[2],outCols=(1,2,13-16)) (merge-join G18 G2 G19 inner-join,+13,+2) │ ├── [ordering: +(2|13)] │ │ ├── best: (merge-join G18="[ordering: +13]" G2="[ordering: +2]" G19 inner-join,+13,+2) - │ │ └── cost: 2418.60 + │ │ └── cost: 2439.80 │ └── [] │ ├── best: (inner-join G2 G18 G25) - │ └── cost: 2189.28 + │ └── cost: 2210.48 ├── 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|6|10)] │ │ ├── best: (sort G17) - │ │ └── cost: 45782.59 + │ │ └── cost: 45813.79 │ └── [] │ ├── best: (inner-join G15 G2 G4) - │ └── cost: 4401.86 + │ └── cost: 4433.06 ├── G18: (scan abc,cols=(13-16)) │ ├── [ordering: +13] │ │ ├── best: (scan abc,cols=(13-16)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ └── [] │ ├── best: (scan abc,cols=(13-16)) - │ └── 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 97f89c8b499e..820cac27f486 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.18 + │ └── cost: 1344.88 └── [] ├── 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: +7]) ├── G1: (project G2 G3 d) │ ├── [presentation: d:4] [ordering: +7] │ │ ├── best: (sort G1) - │ │ └── cost: 1323.99 + │ │ └── cost: 1334.49 │ └── [] │ ├── 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 12d4bd7fbcca..2391ae624c9f 100644 --- a/pkg/sql/opt/xform/testdata/rules/select +++ b/pkg/sql/opt/xform/testdata/rules/select @@ -267,39 +267,39 @@ memo (optimized, ~14KB, required=[presentation: k:1,i:2,f:3,s:4,b:5]) ├── G1: (select G2 G3) (index-join G4 p,cols=(1-5)) (index-join G5 p,cols=(1-5)) (index-join G6 p,cols=(1-5)) (index-join G7 p,cols=(1-5)) │ └── [presentation: k:1,i:2,f:3,s:4,b:5] │ ├── best: (index-join G4 p,cols=(1-5)) - │ └── cost: 49.00 + │ └── cost: 59.80 ├── G2: (scan p,cols=(1-5)) │ └── [] │ ├── best: (scan p,cols=(1-5)) - │ └── cost: 1115.01 + │ └── cost: 1126.01 ├── 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-4),constrained) │ └── [] │ ├── best: (scan p@idx,partial,cols=(1-4),constrained) - │ └── cost: 14.09 + │ └── cost: 24.89 ├── G7: (scan p@idx2,partial,cols=(1,4),constrained) │ └── [] │ ├── best: (scan p@idx2,partial,cols=(1,4),constrained) - │ └── cost: 13.72 + │ └── cost: 24.12 ├── G8: (gt G14 G15) ├── G9: (eq G16 G17) ├── G10: (scan p@idx,partial,cols=(1-4)) │ └── [] │ ├── best: (scan p@idx,partial,cols=(1-4)) - │ └── cost: 14.81 + │ └── cost: 25.61 ├── G11: (filters G8) ├── G12: (scan p@idx2,partial,cols=(1,4)) │ └── [] │ ├── best: (scan p@idx2,partial,cols=(1,4)) - │ └── cost: 350.68 + │ └── cost: 361.08 ├── G13: (filters G9) ├── G14: (variable i) ├── G15: (const 0) @@ -315,16 +315,16 @@ memo (optimized, ~8KB, required=[presentation: i:2]) ├── G1: (project G2 G3 i) │ └── [presentation: i:2] │ ├── 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=(2,4)) │ └── [] │ ├── best: (scan p,cols=(2,4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G5: (filters G6) ├── G6: (eq G7 G8) ├── G7: (variable s) @@ -539,7 +539,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) @@ -564,16 +564,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) @@ -601,16 +601,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) │ └── [] @@ -647,16 +647,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) │ └── [] @@ -708,12 +708,12 @@ memo (optimized, ~9KB, 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) │ └── [] @@ -795,7 +795,7 @@ memo (optimized, ~6KB, 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) │ └── [] @@ -857,12 +857,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) │ └── [] @@ -955,7 +955,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)) │ └── [] @@ -1019,12 +1019,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)) │ └── [] @@ -1083,22 +1083,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) @@ -1244,28 +1244,28 @@ 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="[ordering: +4]") - │ │ └── cost: 1167.94 + │ │ └── cost: 1178.64 │ ├── [ordering: +4] │ │ ├── best: (scan kifs@s_idx,cols=(2-4)) - │ │ └── cost: 1084.71 + │ │ └── cost: 1095.41 │ └── [] │ ├── 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') @@ -1277,21 +1277,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') @@ -1303,16 +1303,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) @@ -1714,49 +1714,49 @@ memo (optimized, ~18KB, required=[presentation: i:2]) ├── G1: (project G2 G3 i) │ └── [presentation: i:2] │ ├── best: (project G2 G3 i) - │ └── cost: 5.00 + │ └── cost: 15.30 ├── G2: (select G4 G5) (select G6 G7) (select G8 G7) (select G9 G7) (project G10 G11 i) │ └── [] │ ├── best: (project G10 G11 i) - │ └── cost: 4.98 + │ └── cost: 15.28 ├── G3: (projections) ├── G4: (scan p,cols=(2,4)) │ └── [] │ ├── best: (scan p,cols=(2,4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G5: (filters G12 G13) ├── G6: (index-join G14 p,cols=(2,4)) │ └── [] │ ├── best: (index-join G14 p,cols=(2,4)) - │ └── cost: 374.63 + │ └── cost: 385.03 ├── G7: (filters G12) ├── G8: (project G15 G11 i) │ └── [] │ ├── best: (project G15 G11 i) - │ └── cost: 14.52 + │ └── cost: 24.82 ├── G9: (index-join G16 p,cols=(2,4)) │ └── [] │ ├── best: (index-join G16 p,cols=(2,4)) - │ └── cost: 70.38 + │ └── cost: 80.78 ├── G10: (scan p@idx2,partial,cols=(2),constrained) │ └── [] │ ├── best: (scan p@idx2,partial,cols=(2),constrained) - │ └── cost: 4.95 + │ └── cost: 15.25 ├── G11: (projections G17) ├── G12: (eq G18 G19) ├── G13: (eq G20 G17) ├── G14: (select G21 G22) │ └── [] │ ├── best: (select G21 G22) - │ └── cost: 354.03 + │ └── cost: 364.43 ├── G15: (scan p@idx2,partial,cols=(2)) │ └── [] │ ├── best: (scan p@idx2,partial,cols=(2)) - │ └── cost: 14.31 + │ └── cost: 24.61 ├── G16: (scan p@idx,partial,cols=(1,4),constrained) │ └── [] │ ├── best: (scan p@idx,partial,cols=(1,4),constrained) - │ └── cost: 13.72 + │ └── cost: 24.12 ├── G17: (const 'foo') ├── G18: (variable i) ├── G19: (const 3) @@ -1764,7 +1764,7 @@ memo (optimized, ~18KB, required=[presentation: i:2]) ├── G21: (scan p@idx,partial,cols=(1,4)) │ └── [] │ ├── best: (scan p@idx,partial,cols=(1,4)) - │ └── cost: 350.68 + │ └── cost: 361.08 └── G22: (filters G13) exec-ddl @@ -1788,16 +1788,16 @@ memo (optimized, ~7KB, required=[presentation: i:2]) ├── G1: (project G2 G3 i) │ └── [presentation: i:2] │ ├── 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=(2,4)) │ └── [] │ ├── best: (scan p,cols=(2,4)) - │ └── cost: 1084.71 + │ └── cost: 1095.41 ├── G5: (filters G6 G7) ├── G6: (eq G8 G9) ├── G7: (eq G10 G11) @@ -2142,20 +2142,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) @@ -4432,27 +4432,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) @@ -4480,11 +4480,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) @@ -5191,6 +5191,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, @@ -5246,40 +5265,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) @@ -5327,45 +5346,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) @@ -5392,32 +5411,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) @@ -5446,40 +5465,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) @@ -5861,59 +5880,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) @@ -5923,7 +5942,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 @@ -5953,32 +5972,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) @@ -5992,16 +6011,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) @@ -7558,39 +7577,39 @@ memo (optimized, ~19KB, 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)) (distinct-on G5 G6 cols=(1),ordering=+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: 697.34 + │ └── cost: 707.74 ├── G5: (union-all G8 G9) │ ├── [ordering: +1] │ │ ├── best: (union-all G8="[ordering: +7]" G9="[ordering: +13]") - │ │ └── cost: 2216.34 + │ │ └── cost: 2237.94 │ └── [] │ ├── 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) │ ├── [ordering: +7] │ │ ├── best: (select G15="[ordering: +7]" G16) - │ │ └── cost: 1104.83 + │ │ └── cost: 1115.63 │ └── [] │ ├── best: (select G15 G16) - │ └── cost: 1104.83 + │ └── cost: 1115.63 ├── G9: (select G18 G19) (select G20 G19) │ ├── [ordering: +13] │ │ ├── best: (select G18="[ordering: +13]" G19) - │ │ └── cost: 1104.83 + │ │ └── cost: 1115.63 │ └── [] │ ├── best: (select G18 G19) - │ └── cost: 1104.83 + │ └── cost: 1115.63 ├── G10: (const-agg G21) ├── G11: (const-agg G22) ├── G12: (const-agg G23) @@ -7599,33 +7618,33 @@ memo (optimized, ~19KB, required=[presentation: k:1,a:2,b:3,c:4]) ├── G15: (scan t58390,cols=(7-10)) │ ├── [ordering: +7] │ │ ├── best: (scan t58390,cols=(7-10)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ └── [] │ ├── best: (scan t58390,cols=(7-10)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── G16: (filters G25) ├── G17: (index-join G26 t58390,cols=(7-10)) │ ├── [ordering: +7] │ │ ├── best: (index-join G26="[ordering: +7]" t58390,cols=(7-10)) - │ │ └── cost: 4895.84 + │ │ └── cost: 4906.24 │ └── [] │ ├── best: (index-join G26 t58390,cols=(7-10)) - │ └── cost: 4744.02 + │ └── cost: 4754.42 ├── G18: (scan t58390,cols=(13-16)) │ ├── [ordering: +13] │ │ ├── best: (scan t58390,cols=(13-16)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ └── [] │ ├── best: (scan t58390,cols=(13-16)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── G19: (filters G27) ├── G20: (index-join G28 t58390,cols=(13-16)) │ ├── [ordering: +13] │ │ ├── best: (index-join G28="[ordering: +13]" t58390,cols=(13-16)) - │ │ └── cost: 4895.84 + │ │ └── cost: 4906.24 │ └── [] │ ├── best: (index-join G28 t58390,cols=(13-16)) - │ └── cost: 4744.02 + │ └── cost: 4754.42 ├── G21: (variable a) ├── G22: (variable b) ├── G23: (variable c) @@ -7634,18 +7653,18 @@ memo (optimized, ~19KB, required=[presentation: k:1,a:2,b:3,c:4]) ├── G26: (scan t58390@secondary,partial,cols=(7,10)) │ ├── [ordering: +7] │ │ ├── best: (sort G26) - │ │ └── cost: 849.16 + │ │ └── cost: 859.56 │ └── [] │ ├── best: (scan t58390@secondary,partial,cols=(7,10)) - │ └── cost: 697.34 + │ └── cost: 707.74 ├── G27: (gt G30 G24) ├── G28: (scan t58390@secondary,partial,cols=(13,16)) │ ├── [ordering: +13] │ │ ├── best: (sort G28) - │ │ └── cost: 849.16 + │ │ └── cost: 859.56 │ └── [] │ ├── best: (scan t58390@secondary,partial,cols=(13,16)) - │ └── cost: 697.34 + │ └── cost: 707.74 ├── G29: (variable a) └── G30: (variable b) @@ -7673,54 +7692,54 @@ 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)) (distinct-on G8 G9 cols=(1),ordering=+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: 1324.08 + │ │ └── cost: 1334.68 │ └── [] │ ├── 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: (union-all G13 G14="[ordering: +(17|18)]") - │ │ └── cost: 1089.79 + │ │ └── cost: 1100.39 │ ├── [ordering: +1] │ │ ├── best: (union-all G13 G14="[ordering: +16]") - │ │ └── cost: 1089.76 + │ │ └── cost: 1100.36 │ └── [] │ ├── 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) @@ -7728,13 +7747,13 @@ memo (optimized, ~28KB, required=[presentation: a:1] [ordering: +2]) ├── G14: (select G28 G29) (select G30 G31) │ ├── [ordering: +(17|18)] │ │ ├── best: (sort G14) - │ │ └── cost: 1084.67 + │ │ └── cost: 1095.27 │ ├── [ordering: +16] │ │ ├── best: (select G28="[ordering: +16]" G29) - │ │ └── cost: 1084.64 + │ │ └── cost: 1095.24 │ └── [] │ ├── best: (select G28 G29) - │ └── cost: 1084.64 + │ └── cost: 1095.24 ├── G15: (const-agg G18) ├── G16: (const-agg G17) ├── G17: (variable t1.c) @@ -7744,15 +7763,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=(11-13)) │ └── [] │ ├── best: (scan t61795 [as=t1],cols=(11-13)) - │ └── cost: 1074.61 + │ └── cost: 1085.21 ├── G24: (filters G35 G36) ├── G25: (scan t61795 [as=t1],cols=(11-13),constrained) │ └── [] @@ -7762,28 +7781,28 @@ memo (optimized, ~28KB, required=[presentation: a:1] [ordering: +2]) ├── G27: (index-join G37 t61795,cols=(11-13)) │ └── [] │ ├── best: (index-join G37 t61795,cols=(11-13)) - │ └── cost: 1049.59 + │ └── cost: 1059.99 ├── G28: (scan t61795 [as=t1],cols=(16-18)) │ ├── [ordering: +16] │ │ ├── best: (scan t61795 [as=t1],cols=(16-18)) - │ │ └── cost: 1074.61 + │ │ └── cost: 1085.21 │ ├── [ordering: +17] │ │ ├── best: (sort G28) - │ │ └── cost: 1324.08 + │ │ └── cost: 1334.68 │ └── [] │ ├── best: (scan t61795 [as=t1],cols=(16-18)) - │ └── cost: 1074.61 + │ └── cost: 1085.21 ├── G29: (filters G38 G39) ├── G30: (index-join G40 t61795,cols=(16-18)) │ ├── [ordering: +16] │ │ ├── best: (index-join G40="[ordering: +16]" t61795,cols=(16-18)) - │ │ └── cost: 3108.48 + │ │ └── cost: 3118.88 │ ├── [ordering: +17] │ │ ├── best: (index-join G40="[ordering: +17]" t61795,cols=(16-18)) - │ │ └── cost: 3040.04 + │ │ └── cost: 3050.44 │ └── [] │ ├── best: (index-join G40 t61795,cols=(16-18)) - │ └── cost: 3040.04 + │ └── cost: 3050.44 ├── G31: (filters G38) ├── G32: (variable t1.a) ├── G33: (const 10) @@ -7793,19 +7812,19 @@ 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) │ ├── [ordering: +16] │ │ ├── best: (sort G40) - │ │ └── cost: 1111.97 + │ │ └── cost: 1122.37 │ ├── [ordering: +17] │ │ ├── best: (select G50="[ordering: +17]" G51) - │ │ └── cost: 1043.53 + │ │ └── cost: 1053.93 │ └── [] │ ├── best: (select G50 G51) - │ └── cost: 1043.53 + │ └── cost: 1053.93 ├── G41: (scalar-list G18) ├── G42: (variable t1.c) ├── G43: (variable t1.b) @@ -7813,7 +7832,7 @@ memo (optimized, ~28KB, required=[presentation: a:1] [ordering: +2]) ├── G45: (scan t61795@secondary [as=t1],cols=(11,12),constrained) │ └── [] │ ├── best: (scan t61795@secondary [as=t1],cols=(11,12),constrained) - │ └── cost: 1033.61 + │ └── cost: 1044.01 ├── G46: (filters G36) ├── G47: (variable t1.c) ├── G48: (variable t1.b) @@ -7821,13 +7840,13 @@ memo (optimized, ~28KB, required=[presentation: a:1] [ordering: +2]) ├── G50: (scan t61795@secondary [as=t1],cols=(16,17),constrained) │ ├── [ordering: +16] │ │ ├── best: (sort G50) - │ │ └── cost: 1270.40 + │ │ └── cost: 1280.80 │ ├── [ordering: +17] │ │ ├── best: (scan t61795@secondary [as=t1],cols=(16,17),constrained) - │ │ └── cost: 1033.61 + │ │ └── cost: 1044.01 │ └── [] │ ├── best: (scan t61795@secondary [as=t1],cols=(16,17),constrained) - │ └── cost: 1033.61 + │ └── cost: 1044.01 ├── G51: (filters G39) └── G52: (scalar-list G48) diff --git a/pkg/sql/opt/xform/testdata/rules/set b/pkg/sql/opt/xform/testdata/rules/set index 405097d6b3c3..7d643ce10d9e 100644 --- a/pkg/sql/opt/xform/testdata/rules/set +++ b/pkg/sql/opt/xform/testdata/rules/set @@ -25,29 +25,29 @@ memo (optimized, ~9KB, required=[presentation: k:13,u:14,v:15,w:16]) ├── G1: (distinct-on G2 G3 cols=(13)) (distinct-on G2 G3 cols=(13),ordering=+13) │ └── [presentation: k:13,u:14,v:15,w:16] │ ├── best: (distinct-on G2="[ordering: +13]" G3 cols=(13),ordering=+13) - │ └── cost: 2309.65 + │ └── cost: 2331.25 ├── G2: (union-all G4 G5) │ ├── [ordering: +13] │ │ ├── best: (union-all G4="[ordering: +1]" G5="[ordering: +7]") - │ │ └── cost: 2209.63 + │ │ └── cost: 2231.23 │ └── [] │ ├── best: (union-all G4 G5) - │ └── cost: 2209.63 + │ └── cost: 2231.23 ├── G3: (aggregations G6 G7 G8) ├── G4: (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: +1] │ │ ├── best: (scan kuvw,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ └── [] │ ├── best: (scan kuvw,cols=(1-4)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── G5: (scan kuvw,cols=(7-10)) (scan kuvw@uvw,cols=(7-10)) (scan kuvw@wvu,cols=(7-10)) (scan kuvw@vw,cols=(7-10)) (scan kuvw@w,cols=(7-10)) │ ├── [ordering: +7] │ │ ├── best: (scan kuvw,cols=(7-10)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ └── [] │ ├── best: (scan kuvw,cols=(7-10)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── G6: (const-agg G9) ├── G7: (const-agg G10) ├── G8: (const-agg G11) @@ -62,45 +62,45 @@ memo (optimized, ~9KB, required=[presentation: k:1,u:2,v:3,w:4]) ├── G1: (intersect-all G2 G3) (intersect-all G2 G3 ordering=+1) (intersect-all G2 G3 ordering=+2,+3,+4,+1) (intersect-all G2 G3 ordering=+4,+3,+2,+1) (intersect-all G2 G3 ordering=+3,+4,+1) (intersect-all G2 G3 ordering=+4,+1) │ └── [presentation: k:1,u:2,v:3,w:4] │ ├── best: (intersect-all G2="[ordering: +1]" G3="[ordering: +7]" ordering=+1) - │ └── cost: 2199.63 + │ └── cost: 2221.23 ├── G2: (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: +1] │ │ ├── best: (scan kuvw,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ ├── [ordering: +2,+3,+4,+1] │ │ ├── best: (scan kuvw@uvw,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ ├── [ordering: +3,+4,+1] │ │ ├── best: (scan kuvw@vw,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ ├── [ordering: +4,+1] │ │ ├── best: (scan kuvw@w,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ ├── [ordering: +4,+3,+2,+1] │ │ ├── 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 └── G3: (scan kuvw,cols=(7-10)) (scan kuvw@uvw,cols=(7-10)) (scan kuvw@wvu,cols=(7-10)) (scan kuvw@vw,cols=(7-10)) (scan kuvw@w,cols=(7-10)) ├── [ordering: +10,+7] │ ├── best: (scan kuvw@w,cols=(7-10)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── [ordering: +10,+9,+8,+7] │ ├── best: (scan kuvw@wvu,cols=(7-10)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── [ordering: +7] │ ├── best: (scan kuvw,cols=(7-10)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── [ordering: +8,+9,+10,+7] │ ├── best: (scan kuvw@uvw,cols=(7-10)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── [ordering: +9,+10,+7] │ ├── best: (scan kuvw@vw,cols=(7-10)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 └── [] ├── best: (scan kuvw,cols=(7-10)) - └── cost: 1094.81 + └── cost: 1105.61 memo expect=GenerateStreamingSetOp SELECT * FROM kuvw INTERSECT ALL SELECT * FROM kuvw @@ -109,45 +109,45 @@ memo (optimized, ~9KB, required=[presentation: k:1,u:2,v:3,w:4]) ├── G1: (intersect-all G2 G3) (intersect-all G2 G3 ordering=+1) (intersect-all G2 G3 ordering=+2,+3,+4,+1) (intersect-all G2 G3 ordering=+4,+3,+2,+1) (intersect-all G2 G3 ordering=+3,+4,+1) (intersect-all G2 G3 ordering=+4,+1) │ └── [presentation: k:1,u:2,v:3,w:4] │ ├── best: (intersect-all G2="[ordering: +1]" G3="[ordering: +7]" ordering=+1) - │ └── cost: 2199.63 + │ └── cost: 2221.23 ├── G2: (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: +1] │ │ ├── best: (scan kuvw,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ ├── [ordering: +2,+3,+4,+1] │ │ ├── best: (scan kuvw@uvw,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ ├── [ordering: +3,+4,+1] │ │ ├── best: (scan kuvw@vw,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ ├── [ordering: +4,+1] │ │ ├── best: (scan kuvw@w,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ ├── [ordering: +4,+3,+2,+1] │ │ ├── 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 └── G3: (scan kuvw,cols=(7-10)) (scan kuvw@uvw,cols=(7-10)) (scan kuvw@wvu,cols=(7-10)) (scan kuvw@vw,cols=(7-10)) (scan kuvw@w,cols=(7-10)) ├── [ordering: +10,+7] │ ├── best: (scan kuvw@w,cols=(7-10)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── [ordering: +10,+9,+8,+7] │ ├── best: (scan kuvw@wvu,cols=(7-10)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── [ordering: +7] │ ├── best: (scan kuvw,cols=(7-10)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── [ordering: +8,+9,+10,+7] │ ├── best: (scan kuvw@uvw,cols=(7-10)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── [ordering: +9,+10,+7] │ ├── best: (scan kuvw@vw,cols=(7-10)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 └── [] ├── best: (scan kuvw,cols=(7-10)) - └── cost: 1094.81 + └── cost: 1105.61 memo expect=GenerateStreamingSetOp SELECT * FROM kuvw EXCEPT SELECT * FROM kuvw @@ -156,45 +156,45 @@ memo (optimized, ~9KB, required=[presentation: k:1,u:2,v:3,w:4]) ├── G1: (except-all G2 G3) (except-all G2 G3 ordering=+1) (except-all G2 G3 ordering=+2,+3,+4,+1) (except-all G2 G3 ordering=+4,+3,+2,+1) (except-all G2 G3 ordering=+3,+4,+1) (except-all G2 G3 ordering=+4,+1) │ └── [presentation: k:1,u:2,v:3,w:4] │ ├── best: (except-all G2="[ordering: +1]" G3="[ordering: +7]" ordering=+1) - │ └── cost: 2199.63 + │ └── cost: 2221.23 ├── G2: (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: +1] │ │ ├── best: (scan kuvw,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ ├── [ordering: +2,+3,+4,+1] │ │ ├── best: (scan kuvw@uvw,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ ├── [ordering: +3,+4,+1] │ │ ├── best: (scan kuvw@vw,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ ├── [ordering: +4,+1] │ │ ├── best: (scan kuvw@w,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ ├── [ordering: +4,+3,+2,+1] │ │ ├── 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 └── G3: (scan kuvw,cols=(7-10)) (scan kuvw@uvw,cols=(7-10)) (scan kuvw@wvu,cols=(7-10)) (scan kuvw@vw,cols=(7-10)) (scan kuvw@w,cols=(7-10)) ├── [ordering: +10,+7] │ ├── best: (scan kuvw@w,cols=(7-10)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── [ordering: +10,+9,+8,+7] │ ├── best: (scan kuvw@wvu,cols=(7-10)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── [ordering: +7] │ ├── best: (scan kuvw,cols=(7-10)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── [ordering: +8,+9,+10,+7] │ ├── best: (scan kuvw@uvw,cols=(7-10)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── [ordering: +9,+10,+7] │ ├── best: (scan kuvw@vw,cols=(7-10)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 └── [] ├── best: (scan kuvw,cols=(7-10)) - └── cost: 1094.81 + └── cost: 1105.61 memo expect=GenerateStreamingSetOp SELECT * FROM kuvw EXCEPT ALL SELECT * FROM kuvw @@ -203,45 +203,45 @@ memo (optimized, ~9KB, required=[presentation: k:1,u:2,v:3,w:4]) ├── G1: (except-all G2 G3) (except-all G2 G3 ordering=+1) (except-all G2 G3 ordering=+2,+3,+4,+1) (except-all G2 G3 ordering=+4,+3,+2,+1) (except-all G2 G3 ordering=+3,+4,+1) (except-all G2 G3 ordering=+4,+1) │ └── [presentation: k:1,u:2,v:3,w:4] │ ├── best: (except-all G2="[ordering: +1]" G3="[ordering: +7]" ordering=+1) - │ └── cost: 2199.63 + │ └── cost: 2221.23 ├── G2: (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: +1] │ │ ├── best: (scan kuvw,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ ├── [ordering: +2,+3,+4,+1] │ │ ├── best: (scan kuvw@uvw,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ ├── [ordering: +3,+4,+1] │ │ ├── best: (scan kuvw@vw,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ ├── [ordering: +4,+1] │ │ ├── best: (scan kuvw@w,cols=(1-4)) - │ │ └── cost: 1094.81 + │ │ └── cost: 1105.61 │ ├── [ordering: +4,+3,+2,+1] │ │ ├── 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 └── G3: (scan kuvw,cols=(7-10)) (scan kuvw@uvw,cols=(7-10)) (scan kuvw@wvu,cols=(7-10)) (scan kuvw@vw,cols=(7-10)) (scan kuvw@w,cols=(7-10)) ├── [ordering: +10,+7] │ ├── best: (scan kuvw@w,cols=(7-10)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── [ordering: +10,+9,+8,+7] │ ├── best: (scan kuvw@wvu,cols=(7-10)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── [ordering: +7] │ ├── best: (scan kuvw,cols=(7-10)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── [ordering: +8,+9,+10,+7] │ ├── best: (scan kuvw@uvw,cols=(7-10)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 ├── [ordering: +9,+10,+7] │ ├── best: (scan kuvw@vw,cols=(7-10)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 └── [] ├── best: (scan kuvw,cols=(7-10)) - └── cost: 1094.81 + └── cost: 1105.61 # There is no benefit to generating a streaming UnionAll. memo expect-not=GenerateStreamingSetOp @@ -251,12 +251,12 @@ memo (optimized, ~8KB, required=[presentation: k:13,u:14,v:15,w:16]) ├── G1: (union-all G2 G3) │ └── [presentation: k:13,u:14,v:15,w:16] │ ├── best: (union-all G2 G3) - │ └── cost: 2209.63 + │ └── cost: 2231.23 ├── G2: (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)) │ └── [] │ ├── best: (scan kuvw,cols=(1-4)) - │ └── cost: 1094.81 + │ └── cost: 1105.61 └── G3: (scan kuvw,cols=(7-10)) (scan kuvw@uvw,cols=(7-10)) (scan kuvw@wvu,cols=(7-10)) (scan kuvw@vw,cols=(7-10)) (scan kuvw@w,cols=(7-10)) └── [] ├── best: (scan kuvw,cols=(7-10)) - └── cost: 1094.81 + └── cost: 1105.61