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() 函数。
我在 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() 函数。