提交 a010ff75 编写于 作者: S Sambitesh Dash

Disable FULL JOIN by default for ORCA

Full joins are sub-optimal in ORCA as they are implemented as a UNION of
Left Outer Join AND Left Anti-Semi Join. However, GPDB provides a full
outer join operator. Therefore, until ORCA implements a more optimal
FULL JOIN, it will fall back to the Postgres legacy query optimizer for
queries with FULL JOINs.

Co-authored by: Sambitesh Dash sdash@pivotal.io
Co-authored by: Ashuka Xue axue@pivotal.io
上级 43da9546
......@@ -530,6 +530,11 @@ CConfigParamMapping::PackConfigParamInBitset
traceflag_bitset->ExchangeSet(GPOPT_DISABLE_XFORM_TF(CXform::ExfJoinAssociativity));
}
if (!optimizer_enable_full_join)
{
traceflag_bitset->ExchangeSet(GPOPT_DISABLE_XFORM_TF(CXform::ExfExpandFullOuterJoin));
}
// enable nested loop index plans using nest params
// instead of outer reference as in the case with GPDB 4/5
traceflag_bitset->ExchangeSet(EopttraceIndexedNLJOuterRefAsParams);
......
......@@ -352,6 +352,7 @@ bool optimizer_enable_hashjoin;
bool optimizer_enable_dynamictablescan;
bool optimizer_enable_indexscan;
bool optimizer_enable_tablescan;
bool optimizer_enable_full_join;
/* Optimizer plan enumeration related GUCs */
bool optimizer_enumerate_plans;
......@@ -2530,6 +2531,16 @@ struct config_bool ConfigureNamesBool_gp[] =
true,
NULL, NULL, NULL
},
{
{"optimizer_enable_full_join", PGC_USERSET, DEVELOPER_OPTIONS,
gettext_noop("Enables the optimizer's support of full outer joins."),
NULL,
GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE
},
&optimizer_enable_full_join,
false,
NULL, NULL, NULL
},
{
{"optimizer_enable_streaming_material", PGC_USERSET, DEVELOPER_OPTIONS,
gettext_noop("Enable plans with a streaming material node in the optimizer."),
......
......@@ -469,6 +469,7 @@ extern bool optimizer_enable_dynamictablescan;
extern bool optimizer_enable_indexscan;
extern bool optimizer_enable_tablescan;
extern bool optimizer_enable_eageragg;
extern bool optimizer_enable_full_join;
/* Optimizer plan enumeration related GUCs */
extern bool optimizer_enumerate_plans;
......
......@@ -687,55 +687,19 @@ create temporary table b as select generate_series(2, 6) as i distributed by (i)
create temporary table c as select generate_series(3, 7) as i distributed by (i);
explain (costs off) select * from a full join b on (a.i=b.i) full join c on (b.i=c.i);
QUERY PLAN
----------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice3; segments: 3)
-> Result
-> Sequence
-> Shared Scan (share slice:id 3:2)
-> Materialize
-> Sequence
-> Shared Scan (share slice:id 3:4)
-> Materialize
------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Hash Full Join
Hash Cond: (b.i = c.i)
-> Hash Full Join
Hash Cond: (a.i = b.i)
-> Seq Scan on a
-> Sequence
-> Shared Scan (share slice:id 3:5)
-> Materialize
-> Seq Scan on b
-> Append
-> Hash Left Join
Hash Cond: (share4_ref2.i = share5_ref2.i)
-> Shared Scan (share slice:id 3:4)
-> Hash
-> Shared Scan (share slice:id 3:5)
-> Result
-> Hash Anti Join
Hash Cond: (share5_ref3.i = share4_ref3.i)
-> Shared Scan (share slice:id 3:5)
-> Seq Scan on b
-> Hash
-> Shared Scan (share slice:id 3:4)
-> Sequence
-> Shared Scan (share slice:id 3:3)
-> Materialize
-> Seq Scan on c
-> Append
-> Hash Left Join
Hash Cond: (share2_ref2.i_1 = share3_ref2.i)
-> Redistribute Motion 3:3 (slice1; segments: 3)
Hash Key: share2_ref2.i_1
-> Shared Scan (share slice:id 1:2)
-> Hash
-> Shared Scan (share slice:id 3:3)
-> Result
-> Hash Anti Join
Hash Cond: (share3_ref3.i = share2_ref3.i_1)
-> Shared Scan (share slice:id 3:3)
-> Hash
-> Redistribute Motion 3:3 (slice2; segments: 3)
Hash Key: share2_ref3.i_1
-> Result
-> Shared Scan (share slice:id 2:2)
Optimizer: PQO version 3.9.0
(47 rows)
Optimizer: Postgres query optimizer
(11 rows)
select * from a full join b on (a.i=b.i) full join c on (b.i=c.i);
i | i | i
......
......@@ -6562,6 +6562,8 @@ select rank() over(partition by a, case when b = 0 then a+b end order by b asc)
-- alias
select foo.d from orca.foo full join orca.bar on (foo.d = bar.a) group by d;
INFO: GPORCA failed to produce a plan, falling back to planner
DETAIL: No plan has been computed for required properties
d
----
1
......@@ -6607,6 +6609,8 @@ select foo.d from orca.foo full join orca.bar on (foo.d = bar.a) group by d;
(40 rows)
select 1 as v from orca.foo full join orca.bar on (foo.d = bar.a) group by d;
INFO: GPORCA failed to produce a plan, falling back to planner
DETAIL: No plan has been computed for required properties
v
---
1
......@@ -6652,6 +6656,8 @@ select 1 as v from orca.foo full join orca.bar on (foo.d = bar.a) group by d;
(40 rows)
select * from orca.r where a in (select count(*)+1 as v from orca.foo full join orca.bar on (foo.d = bar.a) group by d+r.b);
INFO: GPORCA failed to produce a plan, falling back to planner
DETAIL: No plan has been computed for required properties
a | b
---+---
2 | 2
......
......@@ -505,39 +505,18 @@ create table input_table(a varchar(30), b varchar(30)) distributed by (a);
set enable_hashjoin = off;
explain (costs off) select X.a from input_table X full join (select a from input_table) Y ON X.a = Y.a;
QUERY PLAN
--------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice6; segments: 3)
-> Result
-> Sequence
-> Shared Scan (share slice:id 6:0)
-> Materialize
-> Redistribute Motion 3:3 (slice5; segments: 3)
-> Seq Scan on input_table input_table_1
-> Sequence
-> Shared Scan (share slice:id 6:1)
-> Materialize
-> Redistribute Motion 3:3 (slice4; segments: 3)
-----------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Merge Full Join
Merge Cond: ((x.a)::text = (input_table.a)::text)
-> Sort
Sort Key: x.a
-> Seq Scan on input_table x
-> Sort
Sort Key: input_table.a
-> Seq Scan on input_table
-> Append
-> Hash Left Join
Hash Cond: ((share0_ref2.a)::text = (share1_ref2.a)::text)
-> Redistribute Motion 3:3 (slice1; segments: 3)
Hash Key: share0_ref2.a
-> Shared Scan (share slice:id 1:0)
-> Hash
-> Redistribute Motion 3:3 (slice2; segments: 3)
Hash Key: (share1_ref2.a)::text
-> Shared Scan (share slice:id 2:1)
-> Result
-> Hash Anti Join
Hash Cond: ((share1_ref3.a)::text = (share0_ref3.a)::text)
-> Shared Scan (share slice:id 6:1)
-> Hash
-> Broadcast Motion 3:3 (slice3; segments: 3)
-> Result
-> Shared Scan (share slice:id 3:0)
Optimizer: PQO version 2.74.0
(31 rows)
Optimizer: Postgres query optimizer
(10 rows)
-- Cleanup
reset enable_hashjoin;
......@@ -590,29 +569,14 @@ set enable_material = off;
-- The plan still have Material operator
explain (costs off) select * from t6215 a full join t6215 b on true;
QUERY PLAN
----------------------------------------------------------------------------
------------------------------------------
Gather Motion 1:1 (slice1; segments: 1)
-> Result
-> Sequence
-> Shared Scan (share slice:id 1:0)
-> Materialize
-> Seq Scan on t6215 t6215_1
-> Sequence
-> Shared Scan (share slice:id 1:1)
-> Merge Full Join
-> Seq Scan on t6215 a
-> Materialize
-> Seq Scan on t6215
-> Append
-> Nested Loop Left Join
Join Filter: true
-> Shared Scan (share slice:id 1:0)
-> Shared Scan (share slice:id 1:1)
-> Result
-> Nested Loop Anti Join
Join Filter: true
-> Shared Scan (share slice:id 1:1)
-> Shared Scan (share slice:id 1:0)
Optimizer: PQO version 3.9.0
(21 rows)
-> Seq Scan on t6215 b
Optimizer: Postgres query optimizer
(6 rows)
select * from t6215 a full join t6215 b on true;
f1 | f1
......
......@@ -2267,36 +2267,18 @@ select * from
(select * from j2_tbl order by j2_tbl.i desc, j2_tbl.k asc) j2_tbl
on j1_tbl.i = j2_tbl.i and j1_tbl.i = j2_tbl.k;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice5; segments: 3)
-> Result
-> Sequence
-> Shared Scan (share slice:id 5:0)
-> Materialize
-> Redistribute Motion 3:3 (slice4; segments: 3)
-> Seq Scan on j1_tbl
-> Sequence
-> Shared Scan (share slice:id 5:1)
-> Materialize
-> Redistribute Motion 3:3 (slice3; segments: 3)
-----------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Merge Full Join
Merge Cond: ((j2_tbl.i = j1_tbl.i) AND (j2_tbl.k = j1_tbl.i))
-> Sort
Sort Key: j2_tbl.i, j2_tbl.k
-> Seq Scan on j2_tbl
-> Append
-> Hash Left Join
Hash Cond: ((share0_ref2.i = share1_ref2.i) AND (share0_ref2.i = share1_ref2.k))
-> Shared Scan (share slice:id 5:0)
-> Hash
-> Broadcast Motion 3:3 (slice1; segments: 3)
-> Shared Scan (share slice:id 1:1)
-> Result
-> Hash Anti Join
Hash Cond: ((share1_ref3.i = share0_ref3.i) AND (share1_ref3.k = share0_ref3.i))
-> Shared Scan (share slice:id 5:1)
-> Hash
-> Broadcast Motion 3:3 (slice2; segments: 3)
-> Result
-> Shared Scan (share slice:id 2:0)
Optimizer: PQO version 3.9.0
(28 rows)
-> Sort
Sort Key: j1_tbl.i
-> Seq Scan on j1_tbl
Optimizer: Postgres query optimizer
(10 rows)
select * from
j1_tbl full join
......@@ -2843,48 +2825,24 @@ SELECT qq, unique1
USING (qq)
INNER JOIN tenk1 c ON qq = unique2;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice7; segments: 3)
-> Result
-> Nested Loop
Join Filter: true
-> Result
-> Broadcast Motion 3:3 (slice6; segments: 3)
-> Result
-> Sequence
-> Shared Scan (share slice:id 6:0)
-> Materialize
-> Redistribute Motion 3:3 (slice5; segments: 3)
-> Result
-> Seq Scan on int8_tbl int8_tbl_1
-> Sequence
-> Shared Scan (share slice:id 6:1)
-> Materialize
-> Result
-> Redistribute Motion 3:3 (slice4; segments: 3)
-> Seq Scan on int8_tbl
-> Append
-> Hash Left Join
Hash Cond: (share0_ref2.qq = share1_ref2.qq)
--------------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice4; segments: 3)
-> Hash Join
Hash Cond: (c.unique2 = COALESCE((COALESCE(a.q1, 0::bigint)), (COALESCE(b.q2, (-1)::bigint))))
-> Seq Scan on tenk1 c
-> Hash
-> Broadcast Motion 3:3 (slice3; segments: 3)
-> Hash Full Join
Hash Cond: (COALESCE(a.q1, 0::bigint) = COALESCE(b.q2, (-1)::bigint))
-> Redistribute Motion 3:3 (slice1; segments: 3)
Hash Key: share0_ref2.qq
-> Shared Scan (share slice:id 1:0)
Hash Key: COALESCE(a.q1, 0::bigint)
-> Seq Scan on int8_tbl a
-> Hash
-> Redistribute Motion 3:3 (slice2; segments: 3)
Hash Key: share1_ref2.qq
-> Shared Scan (share slice:id 2:1)
-> Result
-> Hash Anti Join
Hash Cond: (share1_ref3.qq = share0_ref3.qq)
-> Shared Scan (share slice:id 6:1)
-> Hash
-> Broadcast Motion 3:3 (slice3; segments: 3)
-> Result
-> Shared Scan (share slice:id 3:0)
-> Index Scan using tenk1_unique2 on tenk1
Index Cond: (unique2 = (COALESCE(share0_ref2.qq, share1_ref2.qq)))
Optimizer: PQO version 2.74.0
(40 rows)
Hash Key: COALESCE(b.q2, (-1)::bigint)
-> Seq Scan on int8_tbl b
Optimizer: Postgres query optimizer
(16 rows)
SELECT qq, unique1
FROM
......@@ -4202,46 +4160,25 @@ select * from
(tenk1 as a1 full join (select 1 as id) as yy on (a1.unique1 = yy.id))
on (xx.id = coalesce(yy.id));
QUERY PLAN
-------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------
Gather Motion 3:1 (slice4; segments: 3)
-> Hash Left Join
Hash Cond: ("outer".id = COALESCE(share1_ref2.id))
-> Result
-> Result
-> Result
-> Hash Right Join
Hash Cond: (COALESCE((1)) = (1))
-> Redistribute Motion 3:3 (slice2; segments: 3)
Hash Key: COALESCE((1))
-> Hash Full Join
Hash Cond: (a1.unique1 = (1))
-> Seq Scan on tenk1 a1
-> Hash
-> Redistribute Motion 3:3 (slice3; segments: 3)
Hash Key: COALESCE(share1_ref2.id)
-> Result
-> Sequence
-> Shared Scan (share slice:id 3:0)
-> Materialize
-> Seq Scan on tenk1
-> Sequence
-> Shared Scan (share slice:id 3:1)
-> Materialize
-> Redistribute Motion 1:3 (slice1; segments: 1)
Hash Key: (1)
-> Result
-> Result
One-Time Filter: (gp_execution_segment() = 2)
-> Result
-> Append
-> Hash Left Join
Hash Cond: (share0_ref2.unique1 = share1_ref2.id)
-> Shared Scan (share slice:id 3:0)
-> Hash
-> Redistribute Motion 3:3 (slice1; segments: 3)
Hash Key: share1_ref2.id
-> Shared Scan (share slice:id 1:1)
-> Redistribute Motion 1:3 (slice3; segments: 1)
Hash Key: (1)
-> Result
-> Hash Anti Join
Hash Cond: (share1_ref3.id = share0_ref3.unique1)
-> Redistribute Motion 3:3 (slice2; segments: 3)
Hash Key: share1_ref3.id
-> Shared Scan (share slice:id 2:1)
-> Hash
-> Shared Scan (share slice:id 3:0)
Optimizer: PQO version 3.9.0
(38 rows)
Optimizer: Postgres query optimizer
(17 rows)
select * from
(select 1 as id) as xx
......@@ -4275,40 +4212,21 @@ explain (costs off)
explain (costs off)
select * from tenk1 a full join tenk1 b using(unique2) where unique2 = 42;
QUERY PLAN
----------------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice4; segments: 3)
-> Result
-> Result
Filter: ((COALESCE(share0_ref2.unique2, share1_ref2.unique2)) = 42)
-> Result
-> Sequence
-> Shared Scan (share slice:id 4:0)
-> Materialize
-> Seq Scan on tenk1 tenk1_1
-> Sequence
-> Shared Scan (share slice:id 4:1)
-> Materialize
-> Seq Scan on tenk1
-> Append
-> Hash Left Join
Hash Cond: (share0_ref2.unique2 = share1_ref2.unique2)
-------------------------------------------------------------------
Gather Motion 3:1 (slice3; segments: 3)
-> Hash Full Join
Hash Cond: (a.unique2 = b.unique2)
-> Redistribute Motion 3:3 (slice1; segments: 3)
Hash Key: share0_ref2.unique2
-> Shared Scan (share slice:id 1:0)
Hash Key: a.unique2
-> Index Scan using tenk1_unique2 on tenk1 a
Index Cond: (unique2 = 42)
-> Hash
-> Redistribute Motion 3:3 (slice2; segments: 3)
Hash Key: share1_ref2.unique2
-> Shared Scan (share slice:id 2:1)
-> Result
-> Hash Anti Join
Hash Cond: (share1_ref3.unique2 = share0_ref3.unique2)
-> Shared Scan (share slice:id 4:1)
-> Hash
-> Broadcast Motion 3:3 (slice3; segments: 3)
-> Result
-> Shared Scan (share slice:id 3:0)
Optimizer: PQO version 2.74.0
(32 rows)
Hash Key: b.unique2
-> Index Scan using tenk1_unique2 on tenk1 b
Index Cond: (unique2 = 42)
Optimizer: Postgres query optimizer
(13 rows)
--
-- test that quals attached to an outer join have correct semantics,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册