在之前的版本中 oracle_fdw 支持对join 进行下推,但有如下的限制:
从24.1版本开始, LightDB 支持对semi-join 进行下推,可以把semi-join转为exists 子查询下推到 Oracle 中。同时也支持对insert select语句中的join 进行下推。
CREATE EXTENSION oracle_fdw;
-- TWO_TASK or ORACLE_HOME and ORACLE_SID must be set in the server's environment for this to work
CREATE SERVER oracle FOREIGN DATA WRAPPER oracle_fdw OPTIONS (dbserver '', isolation_level 'read_committed', nchar 'true');
CREATE USER MAPPING FOR PUBLIC SERVER oracle OPTIONS (user 'SCOTT', password 'tiger');
SELECT oracle_execute(
'oracle',
E'CREATE TABLE t1(id number(10,0) primary key, val1 varchar(10), val2 char(10), val3 varchar2(10))'
);
SELECT oracle_execute(
'oracle',
E'CREATE TABLE t2(id number(10,0) primary key, start_date number(10,0), val1 varchar(10), val2 char(10))'
);
SELECT oracle_execute(
'oracle',
E'CREATE TABLE t3(start_date number(10,0) primary key, val1 varchar(10))'
);
-- gather statistics
SELECT oracle_execute(
'oracle',
E'BEGIN\n'
' DBMS_STATS.GATHER_TABLE_STATS (''SCOTT'', ''T1'', NULL, 100);\n'
'END;'
);
SELECT oracle_execute(
'oracle',
E'BEGIN\n'
' DBMS_STATS.GATHER_TABLE_STATS (''SCOTT'', ''T2'', NULL, 100);\n'
'END;'
);
SELECT oracle_execute(
'oracle',
E'BEGIN\n'
' DBMS_STATS.GATHER_TABLE_STATS (''SCOTT'', ''T3'', NULL, 100);\n'
'END;'
);
CREATE foreign TABLE t1 (
id number(10) OPTIONS (key 'yes') NOT NULL,
val1 varchar(10),
val2 char(10),
val3 text
) SERVER oracle OPTIONS (table 'T1', force_pushdown_where_op 'true');
CREATE foreign TABLE t2 (
id number(10) OPTIONS (key 'yes') NOT NULL,
start_date number(10),
val1 varchar(10),
val2 char(10)
) SERVER oracle OPTIONS (table 'T2', force_pushdown_where_op 'true');
CREATE foreign TABLE t3 (
start_date number(10) OPTIONS (key 'yes') NOT NULL,
val1 varchar(10)
) SERVER oracle OPTIONS (table 'T3');
insert into t1 values(1, '1234', '1234','1234');
insert into t1 values(2, '2234', '2234','2234');
insert into t1 values(3, '2', '2','2');
insert into t1 values(4, '3', '3','3');
insert into t1 values(5, '4', '3','3');
insert into t1 values(6, '5', '3','3');
insert into t2 values(1, '20240118', 'abc', '2');
insert into t2 values(2, '20240118', 'qwe', '2');
insert into t2 values(3, '20240119', 'abc', '2');
insert into t2 values(4, '20240119', 'qwe', '3');
insert into t2 values(5, '20240121', 'zxc', '2');
insert into t2 values(6, '20240119', '', '3');
insert into t3 values('20240118', 'aaa');
insert into t3 values('20240119', 'bbb');
insert into t3 values('20240120', '');
create table t1_copy(
id number(10) NOT NULL,
val1 varchar(10),
val2 char(10),
val3 text
);
lightdb@test_o=# explain (costs false) insert into t1_copy select * from t1 where exists (select * from t2 where t1.id=t2.id);
QUE
RY PLAN
------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------
-----
Insert on t1_copy
-> Foreign Scan
Oracle query: SELECT /*0354f41de5ae3cfec39f466b95199ae0*/ r3."ID", r3."VAL1", r3.
"VAL2", r3."VAL3" FROM "T1" r3 WHERE EXISTS (SELECT 1 FROM "T2" r4 WHERE (r3."ID" = r4."ID
") )
(3 rows)
lightdb@test_o=# explain (costs false) insert into t1_copy select t1.* from t1 join t2 on t1.id = t2.id;
QUERY PLAN
------------------------------------------------------------------------------------------
---------------------------------------------------------------------------
Insert on t1_copy
-> Foreign Scan
Oracle query: SELECT /*8198ab105b0cf1a88507da8440560abf*/ r3."ID", r3."VAL1", r3.
"VAL2", r3."VAL3" FROM ("T1" r3 INNER JOIN "T2" r4 ON (r3."ID" = r4."ID"))
(3 rows)
lightdb@test_o=# explain (costs false) insert into t1_copy select t1.* from t1 left join t2 on t1.id = t2.id;
QUERY PLAN
------------------------------------------------------------------------------------------
--------------------------------------------------------------------------
Insert on t1_copy
-> Foreign Scan
Oracle query: SELECT /*9590092cd58c52862a9f87d57d5cc7b0*/ r3."ID", r3."VAL1", r3.
"VAL2", r3."VAL3" FROM ("T1" r3 LEFT JOIN "T2" r4 ON (r3."ID" = r4."ID"))
(3 rows)
lightdb@test_o=# explain (costs false) insert into t1_copy select t1.* from t1 right join t2 on t1.id = t2.id;
QUERY PLAN
------------------------------------------------------------------------------------------
--------------------------------------------------------------------------
Insert on t1_copy
-> Foreign Scan
Oracle query: SELECT /*5b0638eb17c55e93456a02170c07ed6f*/ r3."ID", r3."VAL1", r3.
"VAL2", r3."VAL3" FROM ("T2" r4 LEFT JOIN "T1" r3 ON (r3."ID" = r4."ID"))
(3 rows)
lightdb@test_o=# explain (costs false) insert into t1_copy select t1.* from t1 full join t2 on t1.id = t2.id;
QUERY PLAN
------------------------------------------------------------------------------------------
--------------------------------------------------------------------------
Insert on t1_copy
-> Foreign Scan
Oracle query: SELECT /*0175371a65b00ef9b62ca21e1910774f*/ r3."ID", r3."VAL1", r3.
"VAL2", r3."VAL3" FROM ("T1" r3 FULL JOIN "T2" r4 ON (r3."ID" = r4."ID"))
(3 rows)