SAS 运行 中的 proc sql 比 SQL 服务器中的 sql 慢 37 倍

proc sql in SAS run 37 times slower than sql in SQL Server

我在 SAS 中有这个过程 sql 步骤需要大约 1.7 秒才能完成,但是,如果我 运行 这个 SQL 通过 SQL 服务器或任何 sql客户端,只需0.04秒即可完成。

从 sastrace 日志中我发现大部分时间都花在 'Total row fetch seconds' 上,这并不能真正解释导致 SAS Proc SQL 和 SQL 客户端之间 3600% 差异的原因.

Summary Statistics for ODBC are:
Total row fetch seconds were:                       1.736099
Total SQL execution seconds were:                   0.000698
Total SQL prepare seconds were:                     0.000168
Total SQL describe seconds were:                    0.003049
Total seconds used by the ODBC ACCESS engine were     1.743318

'Total row fetch seconds' 到底是什么?我该如何改善 运行 时间?

proc sql noprint;
    create table work.out1 as
    select a.search_key,
            a.field1,
            c.field2
    from db.tabl_1 as a
            join
                    db.tabl_2 as b
                    on a.search_key = b.search_key
                    and a.search_key in (&search_key)
            join
                    db.Tabl_3 as c
                    on b.field2 = c.field2
                    and upcase(XXX_field) EQ "XXX";
quit;
&search_key = 19709, 19710, 19711, 19712, .........

编辑:包括 来自 satrace

的详细日志
MPRINT(macro):   proc sql noprint;
SYMBOLGEN:  Macro variable SUBMISSION_STUDY_RUNS resolves to 
            19709, 19710, 19711, 19712, .........
MPRINT(macro):   create table work.out1 as select a.search_key, a.field1, c.field2 from db.tabl_1 as a join db.tabl_2 as b on 
a.search_key = b.search_key and a.search_key in 
(19709, 19710, 19711, 19712, .........) join db.Tabl_3 as c on b.field2 = c.field2 
and upcase(XXX_field) EQ "XXX";
SQLSRV: AUTOCOMMIT is NO for connection 11
SQLSRV: AUTOCOMMIT turned ON for connection id 11


SQLSRV_10181: Prepared: on connection 11
SELECT * FROM "db"."tabl_1"

SQLSRV: AUTOCOMMIT is NO for connection 12
SQLSRV: AUTOCOMMIT turned ON for connection id 12

SQLSRV_10182: Prepared: on connection 12
SELECT * FROM "db"."tabl_2"

SQLSRV: AUTOCOMMIT is NO for connection 13
SQLSRV: AUTOCOMMIT turned ON for connection id 13

SQLSRV_10183: Prepared: on connection 13
SELECT * FROM "db"."Tabl_3"

SQLSRV: AUTOCOMMIT is NO for connection 14
SQLSRV: AUTOCOMMIT turned ON for connection id 14

SQLSRV_10184: Prepared: on connection 14
 select a."search_key", a."field1", c."field2" from "db"."tabl_1" a inner join "db"."tabl_2" b on a."search_key" = b."search_key" inner join 
"db"."Tabl_3" c on b."field2" = c."field2" where ( a."search_key" in (19709, 19710, 19711, 19712, .........) ) and ({fn 
UCASE(c."XXX_field")} = 'XXX')

在SQL客户端查询i 运行:

select a.search_key,
a.field1,
c.field2
from db.tabl_1 as a
join
       db.tabl_2 as b
       on a.search_key = b.search_key
       and a.search_key in (19709, 19710, 19711, 19712, .........)
join
       db.Tabl_3 as c
       on b.field2 = c.field2
       and XXX_field = 'XXX';

评论有点长

您正在比较两个不同的事物 -- 两个完全不同的数据库。据推测,它们在不同的硬件和不同的环境中 运行。第一个假设是数据也不同

其次,如果你想了解性能,那么你需要了解explain。不幸的是,这不是 proc sql 支持的 功能(尽管它可用。

鉴于有限的信息,我猜测 SQL Server 中的表在其上构建了适当的索引,但 SAS 中的表没有。您或许可以添加适当的索引并获得两个系统更接近的性能数字。然而,这只是猜测。

似乎当 SAS 运行 proc sql,尤其是 join 时,它会在执行 join/processing 之前将整个 table 复制到 SAS 内存中。 SQL 服务器上的相同查询只会加入并 return 适合加入的行。

我已经用 SAS 数据步骤替换了所有查询,现在性能更接近我在 SQL 服务器上获得的性能。

如果有人有其他作品请告诉我around/explanation

因为您在一个查询中使用了 UPCASE() 而在另一个查询中没有使用,所以您实际上 运行 不是同一个查询。从您的 SAS 代码中删除 UPCASE() 函数。