【问题标题】:Which statistics is calculated faster in SAS, proc summary?在 SAS,proc summary 中哪些统计数据计算得更快?
【发布时间】:2017-04-20 12:31:25
【问题描述】:

我需要一个理论上的答案。

假设您有一个包含 15 亿行的表(该表是使用 DB2-Blu 创建为基于列的)。

您正在使用 SAS,您将使用 Proc Summary 进行一些统计,例如最小/最大值/平均值、标准差值和 percentile-10、percentile-90 通过您的同行组。

例如,您有 30.000 个对等组,每个对等组中有 50.000 个值(总计 15 亿个值)。

在另一种情况下,您有 300 万个对等组,并且每个对等组中有 50 个值。所以你又拥有了 15 亿个价值。

如果您的对等组较少但每个对等组中的值更多,它会更快吗?或者,如果有更多的同级组,但每个同级组中的值较少,它会更快吗?

我可以测试第一个案例(30.000 个对等组和每个对等组 50.000 个值),大约需要 16 分钟。但我无法测试第二种情况。

如果我有 300 万个对等组并且每个对等组中还有 50 个值,您能否为运行时间编写一个近似预测?

问题的另一个维度。如果我改用Proc SQL,做这些统计会更快吗?

示例代码如下:

proc summary data = table_blu missing chartype;
   class var1 var2; /* Var1 and var2 are toghether peer-group  */
   var values;

   output out = stattable(rename = (_type_ = type) drop = _freq_)
   n=n min=min max=max mean=mean std=std q1=q1 q3=q3 p10=p10 p90=p90 p95=p95 
;
run;

【问题讨论】:

  • 数据是按组排序还是按组有索引?您使用的是CLASS 还是BY 语句?
  • @DomPazz 我们的系统管理员说在 DB2-Blu(基于列)中不需要索引,它本身有某种智能解决方案。它的执行速度确实比基于行的索引表快了一倍。
  • @DomPazz 我在Proc Summary中使用Class
  • 我认为您需要特别验证的一件事是百分位数计算。数据库似乎对这个计算有问题,所以如果 DB2-Blu 有一个特定的百分位数函数会有所帮助。您是否可以选择使用 SQL Pass through?在 DB2 SQL 中将查询传递给 DB2 可能是最快的方法。

标签: sql sas statistics db2 proc-sql


【解决方案1】:

所以这里有很多事情需要考虑。

就性能而言,第一点并且很可能是最大的一点是将数据从 DB2 导入 SAS。 (我假设这不是 SAS 的数据库实例——如果是,请纠正我)。那是一张大桌子,在电线上移动它需要时间。因此,如果您可以在 DB2 中使用 SQL 语句计算所有这些统计信息,那可能是您最快的选择。

所以假设您已将表格下载到 SAS 服务器:

CLASS 变量排序的表比未排序的表处理起来要快得多。如果 SAS 知道表已排序,则不必扫描表中的记录即可进入组,它可以进行块读取而不是随机 IO。

如果表未排序,则组数越大,则必须发生的表扫描越多。

关键是,在未排序的过程中,将数据从 HD 获取到 CPU 的速度至关重要。

从那里,您会遇到内存和 cpu 问题。 PROC Summary 是多线程的,SAS 将一次读取 N 个组。如果组大小可以适合为该线程分配的内存,则不会有问题。如果组大小太大,那么 SAS 将不得不分页。

我将问题缩小到 15M 行示例:

%let grps=3000;
%let pergrp=5000;

未分类:

NOTE: There were 15000000 observations read from the data set
      WORK.TEST.
NOTE: The data set WORK.SUMMARY has 3001 observations and 9
      variables.
NOTE: PROCEDURE SUMMARY used (Total process time):
      real time           20.88 seconds
      cpu time            31.71 seconds

排序:

NOTE: There were 15000000 observations read from the data set
      WORK.TEST.
NOTE: The data set WORK.SUMMARY has 3001 observations and 9
      variables.
NOTE: PROCEDURE SUMMARY used (Total process time):
      real time           5.44 seconds
      cpu time            11.26 seconds

==============================

%let grps=300000;
%let pergrp=50;

未分类:

NOTE: There were 15000000 observations read from the data set
      WORK.TEST.
NOTE: The data set WORK.SUMMARY has 300001 observations and 9
      variables.
NOTE: PROCEDURE SUMMARY used (Total process time):
      real time           19.26 seconds
      cpu time            41.35 seconds

排序:

NOTE: There were 15000000 observations read from the data set
      WORK.TEST.
NOTE: The data set WORK.SUMMARY has 300001 observations and 9
      variables.
NOTE: PROCEDURE SUMMARY used (Total process time):
      real time           5.43 seconds
      cpu time            10.09 seconds

我运行了几次,运行时间相似。排序时间大致相等并且速度更快。

组越多/每组越少,未排序的速度越快,但查看总 CPU 使用率,它会更高。我的笔记本电脑有一个非常快的 SSD,所以 IO 可能不是限制因素——HD 能够跟上多核 CPU 的需求。在 HD 较慢的系统上,总运行时间可能不同。

最后,这在很大程度上取决于数据的结构以及服务器和数据库的具体情况。

【讨论】:

    【解决方案2】:

    不是理论上的答案,但仍然与 IMO 相关......

    要在大表上加快 proc summary 的速度,请将 / groupinternal 选项添加到您的类语句中。当然,假设您不希望在分组之前对变量进行格式化。

    例如:

    class age / groupinternal;
    

    这告诉 SAS 在计算将值分组到哪个类之前,它不需要对值应用格式。即使您没有明确指定一个格式,每个值都将应用一种格式。这在小桌子上没有太大区别,但在大桌子上却可以。

    通过这个简单的测试,它将我机器上的时间从 60 秒减少到 40 秒 (YMMV):

    data test;
      set sashelp.class;
      do i = 1 to 10000000;
        output;
      end;
    run;
    
    proc summary data=test noprint nway missing;
       class age / groupinternal;
       var height;
       output out=smry mean=;
    run;
    

    【讨论】:

    • 好提示。有趣的是,在我的 3000x5000 未排序表的示例中,这减慢了处理速度。总 CPU 使用率较低,但总时间较高。努力了解原因。
    猜你喜欢
    • 2010-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-15
    • 1970-01-01
    • 1970-01-01
    • 2018-10-13
    相关资源
    最近更新 更多