PROC DATASETS中的索引,SAS和ORACLE库的PROC SQL

时间:2018-05-29 10:19:45

标签: oracle indexing sas proc-sql

我对SAS中索引的使用感到有点困惑。

我找到了两种方法来实现它们:

with PROC SQL

CREATE <UNIQUE> INDEX index-name 
 ON table-name ( column <, ... column>);  

with PROC DATASETS

proc datasets library=college;
   modify survey;
      index create class;
      index create major;
run;

proc datasets library=college;
   modify maillist;
      index create zipid=(zipcode schoolid);
run;

proc datasets library=college;
   modify student;
      index create idnum / unique;
run;

proc datasets library=college;
   modify student;
      index create religion / nomiss;
run;

我的第一个问题是,他们做同样的事吗?我会假设他们这样做,但鉴于文档似乎没有交叉引用它们,并且nomissPROC SQL没有选项,我有一些疑问。

我的第二个问题是,鉴于我有Oracle库和SAS库,ORACLE中定义的索引与SAS中定义的索引之间的关系是什么?

以下查询运行速度非常快,因为该表已在Oracle DB中编制索引:

PROC SQL;
  SELECT * FROM ORACLELIB.MY_TABLE
  WHERE RELATION_ID = 1097;
QUIT;

但是,如果我尝试在1列,1个观察点,位于我的WORK库中的索引表中进行简单的内连接,则查询需要花费大量时间:

data TEST;
   input RELATION_ID;
   datalines;
   1097
;

proc datasets library=WORK;
   modify TEST;
      index create RELATION_ID;
run;

PROC SQL;
  SELECT * FROM ORACLELIB.MY_TABLE t1
  INNER JOIN TEST t2
  ON t1.RELATION_ID = t2.RELATION_ID;
QUIT;

这也很慢:

PROC SQL;
  SELECT * FROM ORACLELIB.MY_TABLE t1
  WHERE RELATION_ID IN (SELECT RELATION_ID FROM TEST);
QUIT;

我还尝试在oracle库中创建我的测试表,该库不在同一个oracle服务器上):

data ORACLELIB2.TEST;
   input RELATION_ID;
   datalines;
   1097
;

这似乎同样缓慢(在这种情况下,我不能因为限制而对其进行索引,但它只是一次观察)。

这导致了我的上一个问题,我该怎样做才能使这个联接运行得尽可能快?

附加说明:

我有3台服务器:

  • 主要的ORACLE服务器,我无法编写,其中包含以MY_TABLE为特色的库
  • 我可以写的另一个ORACLE服务器。
  • 我可以写的SAS服务器

我的主要用途是以下类型的查询:

CREATE TABLE NEWTABLE AS
SELECT *columns* FROM smaller_table t1 LEFT JOIN MY_TABLE t2
ON t1.RELATION_ID = t2.RELATION_ID and t1.other_col = t2.other col
WHERE *additional restrictions on t2*;

3 个答案:

答案 0 :(得分:2)

您需要调查将记录远程库引擎正在执行的操作的SASTRACE=选项(9.2 docs)。我原本期望引擎在简单连接上执行它自己的隐式传递。该引擎将自动将一些SAS功能和分组子句转换为Oracle端口等效项。

如果您无法让服务器端以预期的快速方式运行,那么对于少量ID {几千}},请考虑生成IN列表的代码,看看它是否表现更好。

proc sql noprint;
  select relation_id into :id_list separated by ',' from test;

  SELECT * FROM ORACLELIB.MY_TABLE t1
  WHERE RELATION_ID IN (&id_list);
quit;

如果id是字符,代码生成器将必须quote()选择中的值。

答案 1 :(得分:1)

实际上,有三种方法可以在SAS中创建索引:

  1. Proc数据集/修改/索引创建
  2. 数据集选项(index =)和
  3. Proc SQL / Create Index
  4. AFAIK,除了Unique之外,前两个是指定选项的唯一方法。

    如何更快地加入联系的答案可能涉及Oracle数据库中的(直通)处理和SAS中的前/后处理的组合。并且可能涉及或不涉及创建索引。

    这取决于:

    • a)您的数据和数据大小,以及
    • b)你在结果方面想要达到的目标。

    您能提供更多信息吗?

    编辑:好的,Oracle中的大表,SAS中的小表,小表是输出行的驱动程序

    在不知道绝对详细信息的情况下,查询速度慢的原因与索引关系不大,而是与您&#34;拉动&#34;通过来自大型Oracle表的数据来满足查询。

    根据理查德更新的答案的最后一句,轻松修复:将小表转移到Oracle ...

    要清楚,将小表转移到Oracle,在那里运行查询并将结果保存在那里。如果需要,使用适当的传输工具将数据导出到SAS ......

答案 2 :(得分:1)

关于

  

如果我将测试表移动到oracle库,这些查询仍然存在   慢(在这种情况下,由于限制,我不能将其编入索引,但仅限于此   一个观察)。

你是如何转向Oracle的?附: ORACLELIB不是有效的SAS libref,所以我猜这是伪代码。

查看SAS/ACCESS® 9.4 for Relational Databases: Reference, Ninth Edition,示例:创建并加入永久表和临时表。

示例包含dbmstemp=yes libname选项和

  

显示如何使用此选项创建永久和临时表   然后将它们加入查询。

您还可以将测试表数据上载到连接会话TEMP表中,然后通过传递SQL查询选择结果集。传递查询将使您可以完全控制查询,包括SAS远程库引擎可能无法使用的主机特定功能(例如,强制索引使用的Oracle提示)。

无论加入方式如何,系统间转移可能是最耗时的方面之一。您希望找到最少转移的工作方式。