【问题标题】:Convert Proc Sql Exists Query to Data Step将 Proc Sql 存在查询转换为数据步骤
【发布时间】:2016-04-11 12:18:22
【问题描述】:

我当前的代码中有这个 proc sql 查询。不幸的是,我正在处理超过 1000 万条记录,因此需要数小时才能运行。我一直在尝试将其转换为数据步骤,认为它会运行得更快。但是,我似乎无法获得相同的数据结果。如果有人可以帮助我完成数据步骤,我将不胜感激。或者,如果您对如何使 proc sql 更有效地运行有任何建议。

这是我的 proc sql 查询:

proc sql;
  create table test as
  select *
  from table1 a
  where exists (select 1
                from table2 b
                where b.acct_id = a.acct_id);
quit;

这是我尝试将其转换为的数据步骤:

proc sort data=table1; by acct_id; run;
proc sort data=table2; by acct_id; run;

data test;
  merge table1   (in=a)
        table2   (in=b);
  by acct_id;
  if a and b;
run;

【问题讨论】:

  • select * from table1 where acct_id in (select acct_id from table2) 的执行速度更快吗? (该查询可能会使查询计划者的意图更清楚 - 希望节省索引/排序/连接的需要)
  • 至少在 SAS 9.3 中,proc sql 在优化 IN/EXIST 语句方面相当糟糕。
  • 我刚刚根据你的建议做了一个小规模的测试,它似乎快得多(11 分钟对 32 秒)。我现在要试一试,看看效果如何。

标签: sas proc-sql datastep


【解决方案1】:

在 SQL 中尝试内连接。您必须列出需要匹配的每个变量。

create table test as
select *
    from
        table1 as a
      inner join
        table2 as b
      on a.acct_id = b.acct_id
      and a.var1 = b.var2 
        ....
      ;

这应该避免我怀疑你的时间被花费的内部选择。

如果这太慢,那么考虑在两个表中的 acct_id 上放置一个索引。这应该会加快加入速度。

【讨论】:

  • 只要 table2 适合会话内存,这将导致哈希连接,与使用 datastep 哈希表相同。应该是最快的解决方案。
【解决方案2】:

至于为什么您当前的数据步骤不起作用很可能是因为您在 table2 上有重复的键(这会扭曲存在 1-N 或 N-N 合并的观察结果)。如果您将排序修改为仅保留键并删除重复项,则合并应该会产生预期的结果。

proc sort data=table1; by acct_id; run;
proc sort data=table2 (keep=acct_id) out=wanted_accounts nodupkey; by acct_id; run;

data test;
merge table1 (in=a)
      wanted_accounts (in=b);
by acct_id;
if a and b;
run;

【讨论】:

    猜你喜欢
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 2022-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多