我有一个包含1M行的Oracle表。我在SAS中有一个oracle表的子集,其中有3000行。我想从oracle表中删除这3000行。
Oracle Table columns are
Col1 Col2 Col3 timestamp
SAS Table columns are:
Col1 Col2 Col3
Oracle表唯一的附加列是时间戳。这是我目前使用的代码,但它耗费了大量时间。
libname ora oracle user='xxx' password='ppp' path = abcd;
PROC SQL;
DELETE from ora.oracle_table a
where exists (select * from sas_table b where a.col1=B.col1 AND a.col2=B.col2 AND A.col3=B.col3 );
QUIT;
请告知如何使其更快更有效。
谢谢!
答案 0 :(得分:2)
一种选择是将SAS表推送到Oracle,然后使用oracle-side命令执行删除。我不确定SAS究竟是如何将上述代码转换为特定于DBMS的代码,但它可能会通过网络推送大量数据,具体取决于它如何优化查询;特别是,如果它必须在本地而不是在数据库上执行连接,那将是非常昂贵的。此外,Oracle可以使用完全本机操作更快地执行删除。
IE:
libname ora ... ;
data ora.gtt_tableb; *or create a temporary or GT table in Oracle and insert into it via proc sql;
set sas_tableb;
run;
proc sql;
connect to oracle (... );
execute (
delete from ...
) by connection to oracle;
quit;
与使用LIBNAME连接相比,这可能会带来显着的性能提升。
如果你没有充分利用PK的索引,可能会有进一步的改进,如果你还没有。
答案 1 :(得分:1)
创建一些测试数据以显示
data test1 test2;
do i=1 to 10;
do j=1 to 10;
do k=1 to 10;
output;
end;
end;
end;
run;
data todel;
do i=1 to 3;
do j=1 to 3;
do k=1 to 3;
output;
end;
end;
end;
run;
proc sql noprint;
delete from test1 as a
where a.i in (select distinct i from todel)
and a.j in (select distinct j from todel)
and a.k in (select distinct k from todel);
quit;
proc sql noprint;
delete from test2 as a
where exists (select * from todel as b where a.i=b.i and a.j=b.j and a.k=b.k);
quit;
答案 2 :(得分:0)
/*---create a temp table in oracle---*/
libname ora oracle user='xxx' password='ppp' path = abcd;
proc append base=ora.TEMP_TABLE data=SAS.sas_TABLE;
run;
/*-----delete the rows using the temp table--------*/
proc sql;
connect to oracle(......);
execute (delete from ORA.ORACLE_TABLE a
where exists (select * from ora.TEMP_TABLE b where a.col1=B.col1 AND a.col2=B.col2 AND A.col3=B.col3)
) by oracle;
quit;
非常感谢你们!感谢您的反馈。