【问题标题】:Joining tables from two Oracle databases in SAS在 SAS 中连接来自两个 Oracle 数据库的表
【发布时间】:2018-03-22 21:42:09
【问题描述】:

我将位于两个单独的 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;

但是查询速度非常慢。您能否建议任何更好的选项来加快此类查询(在创建数据库链接的过程中创建数据库链接)?

非常感谢您查看此内容。

【问题讨论】:

    标签: database oracle join sas


    【解决方案1】:

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

    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 会在单独的 LIBNAME 上进行隐式传递; SAS 很难判断是否可以通过传递来做到这一点。
    • 不太确定。取决于库名称。例如,如果两个不同的库指向同一个东西,我认为 SAS 至少足够聪明,可以解决这个问题。
    【解决方案2】:

    选择适用于每个表中的所有列,内连接仅针对 id 值。因为连接标准评估是针对来自不同来源的数据,所以所有列的包袱可能是时间的一个重要因素,因为即使是不匹配的行也必须在 ON 期间下载(通过 libname 引擎,在 SQL 执行上下文中)评估。

    一种方法是:

    • 仅从每个表中选择 id
    • 找到路口
    • 将交集上传到每个服务器(作为临时表)
    • 利用每台服务器上的交集作为 SAS 最终连接中的通过选择标准

    根据 id 匹配的预期数量、每个表中不同 id 的数量或将 table-1 和 table-2 知道为 SMALL 和 BIG,有几个变化。对于需要传输回服务器的大量 id 匹配项,您可能需要使用某种形式的批量复制。对于交集中相对少量的 id,您可以使用构造 IN () 在 SQL 语句中直接枚举它们。 SQL 语句的大小可能会受到数据库、SAS/ACCESS to 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)
        ));
        ...
    

    对于表 1 和表 2 的 id 数量非常多且超出 SAS 平台资源容量的情况,您还必须针对 id 计数范围迭代该方法。每次迭代的范围标准确定技术是另一天的故事。

    【讨论】:

      猜你喜欢
      • 2011-10-29
      • 1970-01-01
      • 2014-10-05
      • 1970-01-01
      • 2012-12-24
      • 2020-07-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多