从SAS中的两个Oracle数据库连接表

时间:2017-10-11 09:18:10

标签: database oracle join sas

我将两个表连接在一起,这两个表位于两个独立的oracle数据库中。

我目前在sas中通过为每个数据库创建两个libname连接,然后使用类似下面的内容来完成此操作。

libname dbase_a oracle user= etc... ;
libname dbase_b oracle user= etc... ;

proc sql;
create table t1 as 

select a.*, b.*
from dbase_a.table1 a inner join dbase_b.table2 b
on a.id = b.id;
quit;

但是查询速度很慢。你能否建议任何更好的选择来加速这样的查询(在创建数据库链接的路径上创建一个数据库链接)?

非常感谢你看到这个。

2 个答案:

答案 0 :(得分:2)

如果这两个数据库位于同一台服务器上,并且您能够在Oracle中执行跨数据库查询,则可以尝试使用SQL传递:

proc sql;
connect to oracle (user= password= <...>);
create table t1 as
select * from connection to oracle (
  select a.*, b.*
  from dbase_a.schema_a.table1 a
  inner join dbase_b.schema_b.table2 b
    on a.id = b.id;
);
disconnect from oracle;
quit;

我认为,在大多数情况下,SAS会尽可能地在数据库服务器上执行查询,即使没有明确指定传递。但是,当该查询查询不同服务器上的表,不允许跨数据库查询的系统上的不同数据库,或者查询包含SAS无法在DBMS系统上有效转换的SAS特定函数时,然后SAS确实会采取“下载”的方式。完整的表并在本地处理查询,这显然是非常低效的。

答案 1 :(得分:0)

select表示每个表中的所有列,内部联接仅位于 id值。因为连接标准评估是针对来自不同来源的数据,所以所有列的行李都可能是时间的一个重要因素,因为在ON期间必须下载(通过libname引擎,在SQL执行上下文中)不匹配的行评价。

一种方法是:

  • 仅选择每个表中的ID
  • 找到交叉点
  • 将交叉点上传到每个服务器(作为临时表)
  • 利用每台服务器上的交叉点作为SAS中最终连接中的选择标准。

根据预期的id匹配数,每个表中不同ID的数量,或知道table-1和table-2为SMALL和BIG,有几种变体。对于需要传输回服务器的大量id匹配,您可能希望使用某种形式的批量复制。对于交集中相对较少的id,您可以使用构造 IN()直接在SQL语句中枚举它们。 SQL语句的大小可能受数据库,SAS / ACCESS到ORACLE引擎,SAS宏系统的限制。

考虑一个数据场景,其中确定匹配ID的潜在数量对于(id-1,... id-n)中的构造来说太大了。在这种情况下,匹配ID列表以表格方式处理:

libname SOURCE1 ORACLE ....;
libname SOURCE2 ORACLE ....;

libname SCRATCH1 ORACLE ... must specify a scratch schema ...;
libname SCRATCH2 ORACLE ... must specify a scratch schema ...;

proc sql;
    connect using SOURCE1 as PASS1;
    connect using SOURCE2 as PASS2;

    * compute intersection from only id data sent to SAS;
    create table INTERSECTION as
    (select id from connection to PASS1 (select id from table1))
    intersect
    (select id from connection to PASS2 (select id from table2))
    ;

    * upload intersection to each server;
    create table SCRATCH1.ids as select id from INTERSECTION;
    create table SCRATCH2.ids as select id from INTERSECTION;

    * compute inner join from only data that matches intersection;
    create table INNERJOIN as select ONE.*, TWO.* from
    (select * from connection to PASS1 (
        select * from oracle-path-to-schema.table1 
        where id in (select id from oracle-path-to-scratch.ids)
    ))
    JOIN
    (select * from connection to PASS2 (
        select * from oracle-path-to-schema.table2
        where id in (select id from oracle-path-to-scratch.ids)
    ));
    ...

对于table-1和table-2都具有超过SAS平台资源容量的大量id的情况,您还必须迭代id计数范围的方法。每次迭代的范围标准确定技术是另一天的故事。