Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Proc SQL:SAS如何/何时移动数据_Sas - Fatal编程技术网

Proc SQL:SAS如何/何时移动数据

Proc SQL:SAS如何/何时移动数据,sas,Sas,我是DBA/R用户。我刚刚在一个满是SAS用户的办公室里找到了一份工作,我正在努力更好地了解SAS的proc sql是如何工作的。据我所知,SAS包括一个关系数据库,它能够对Oracle等外部服务器运行proc sql。我试图更好地理解它何时/如何决定使用数据库服务器而不是其内部数据库系统 我见过一些真正的S.L.O.W.SAS代码,其中我的同事运行一系列proc sql命令。这些程序通常包括3-5个proc sql步骤。每个proc sql命令都会创建一个本地SAS表。他们没有使用passth

我是DBA/R用户。我刚刚在一个满是SAS用户的办公室里找到了一份工作,我正在努力更好地了解SAS的proc sql是如何工作的。据我所知,SAS包括一个关系数据库,它能够对Oracle等外部服务器运行proc sql。我试图更好地理解它何时/如何决定使用数据库服务器而不是其内部数据库系统

我见过一些真正的S.L.O.W.SAS代码,其中我的同事运行一系列proc sql命令。这些程序通常包括3-5个proc sql步骤。每个proc sql命令都会创建一个本地SAS表。他们没有使用passthrough sql。数据集很大(100万行以上),这些proc-sql步骤运行缓慢。大多数数据保存在服务器上。通常有一个小表定义我们要查看的人口,它位于SAS数据文件中,但其他所有内容都位于服务器上

通过直接在服务器上运行所有查询,我已经演示了速度上的显著提高。(在本例中是Oracle,但我认为这并不重要。)通常,我必须首先将一个表上载到我的个人模式,该模式定义了我们要检查的客户机的数量。其他一切都在服务器上。有时我会将它们的查询折叠在一起,因为它们可以在一个步骤中完成,但我不相信这就是为什么我的程序版本要快得多的原因

我认为procsql会上传初始数据集,然后在服务器上运行第一个查询。然后将输出下载到本地计算机,创建本地SAS数据集。对于第二个procsql步骤,它将在第一步中创建的表上载回服务器,然后在服务器上运行查询。更糟糕的是,“本地”SAS数据集实际上存储在远程服务器上,而不是实际的本地机器上。这对SAS来说是不可见的,但它确实意味着我们再次通过网络复制数据。我认为SAS运行缓慢,因为存在大量不必要的网络流量

问题#1-我对proc sql的理解正确吗?我们真的在浪费我认为我们在网络上上传和下载大型表/数据集的时间吗

Qeustion#2-是否有某种方法可以控制proc sql何时针对服务器运行,何时针对本地数据库运行?在某些情况下,如果我们能够阻止上传/下载步骤,查询将运行得更高效。

Short-response 你的理解并不完全正确,但大致正确。SQL可能没有将SAS数据集发送到服务器,它更可能将服务器数据下载到SAS,但它可能正在下载整个表,而不受连接条件的限制。你的解决方案正是我所建议的——希望你的同事也能加入


长话短说 就处理工作方式而言,这取决于您的代码
PROC SQL
将在本地执行代码(如中,在SAS服务器/桌面上),除非它决定将查询传递到服务器,并且没有被告知不允许这样做。这称为
隐式传递
。除了完全关闭它(使用
PROC SQL
语句上的
noipassthru
),您无法真正控制它。有时可以使用
options msglevel=i
(一个系统选项)和
\u方法
\u树
查看SQL决定做什么(类似于解释计划)

我曾经遇到过这样的情况:SQL Server不敏感地运行字符比较,而SAS不敏感地运行字符比较,我有一个特定的查询,有时发送到服务器,有时不依赖于数据的详细信息。我在检查用例时不够仔细,所以当它确实不正确时(比较Propcase和UPCASE),它似乎可以工作

一般规则是,在以下情况下,SAS将尝试将查询发送到服务器:

  • 查询中的数据已完全驻留在服务器上
  • 查询非常简单,SAS可以很容易地找出如何用其本机语言告诉服务器进行查询
如果使用本地SAS数据集运行查询(例如,在本地将服务器表连接到SAS数据集),它将不会(至少据我所知)转到服务器。它应该始终在本地运行,这意味着从服务器下载贡献表中的所有数据(如果查询中有逻辑筛选器,则可能会进行筛选)。IE(这些示例不一定是好的SQL代码,只是概念示例):

libname或lib-oracle[连接信息];
proc-sql;
*有可能通过;
选择tableA.*,tableB.cost
从oralib.tableA内部连接oralib.tableB
表A.id=表B.id;
*可能不会通过;
选择tableA.*,tableB.cost
从oralib.tableA内部联接work.tableB
表A.id=表B.id;
*可能通过,也可能不通过;
选择tableA.*、tableB.cost、tableC.productID
从oralib.tableA内部连接oralib.tableB
在tableA.id=tableB.id上
左连接oralib.tableC
表a.id=表c.id;
*这会下载数据,但可能会应用where语句服务器端;
选择tableA.*,tableB.cost
从oralib.tableA内部联接work.tableB
在tableA.id=tableB.id上
其中表A.date<'2010年1月1日'd;
退出
在第二个查询的情况下,它可能会将所有tableA都拉下来。在第四个查询中,它可能会将where子句传递给服务器(假设日期不会引起问题,但不应该,SAS知道如何将日期转换为oracle类型的日期)

请注意,SAS进程还可以生成直通。PROC MEANS等将向Oracle发送指令,以便执行MEANS/sums等操作(如果可以轻松执行)

您的最佳选择是:

  • 试着做你能做的每件事(这是有道理的)。确保它进入服务器的唯一方法是使用passthroughlibname oralib oracle [connection info]; proc sql; *Will pass through likely; select tableA.*, tableB.cost from oralib.tableA inner join oralib.tableB on tableA.id=tableB.id; *Will probably not pass through; select tableA.*, tableB.cost from oralib.tableA inner join work.tableB on tableA.id=tableB.id; *Might pass through, might not; select tableA.*, tableB.cost, tableC.productID from oralib.tableA inner join oralib.tableB on tableA.id=tableB.id left join oralib.tableC on tableA.id=tableC.id; *This downloads the data but probably applies the where statement server side; select tableA.*, tableB.cost from oralib.tableA inner join work.tableB on tableA.id=tableB.id where tableA.date < '01JAN2010'd; quit;