Data Step调用SAS宏是否串行?能否基于现有策略实现并行?
场景说明
我有一张名为process_table的表,结构如下:
| table | index |
|---|---|
| TABLE_001 | 1 |
| TABLE_002 | 2 |
| TABLE_003 | 3 |
| TABLE_004 | 4 |
编写了宏%create_table_type_a,用于根据process_table中的表名生成后缀为_A的表(例如输入TABLE_001时生成temp.TABLE_001_A),宏代码如下:
%macro create_table_type_a(table_name); proc sql; create table temp.&table_name._A as select /*some process*/ from &table_name; quit; %mend create_table_type_a;
随后通过Data Step调用该宏:
data _null_; set process_table; call execute('%create_table_type_a('||table||')'); run;
疑问解答
1. SAS处理这些宏调用是串行执行还是并行执行?
通过call execute触发的宏调用是串行执行的。SAS默认情况下会按Data Step生成宏调用的顺序,逐个执行%create_table_type_a宏内的proc sql步骤,完成一个表的处理后才会启动下一个。这是因为Base SAS的核心过程(包括默认proc sql)本身为单线程串行运行,call execute仅将宏调用语句按顺序放入执行队列,不会触发并行任务。
2. 若为串行执行,能否基于当前策略实现并行处理?
可以基于现有逻辑改造实现并行,核心是利用SAS的分布式处理框架或异步任务提交机制,以下是两种可行方案:
方案一:SAS Viya分布式并行(企业级环境首选)
如果使用SAS Viya,可直接借助其分布式计算能力,将proc sql替换为支持分布式执行的proc fedsql,无需大幅修改调用逻辑:
%macro create_table_type_a(table_name); proc fedsql; create table temp.&table_name._A as select /*some process*/ from &table_name; quit; %mend create_table_type_a;
Viya会自动将任务拆分到多个计算节点并行执行,call execute生成的宏调用会触发分布式任务,实现多表同时处理。
方案二:SAS/CONNECT异步远程任务(Base SAS环境适用)
在Base SAS环境中,可通过SAS/CONNECT建立多个远程会话,将不同表的处理任务分配到不同会话并行执行:
- 先定义远程会话池:
signon sess1 user='xxx' password='xxx' server='server1'; signon sess2 user='xxx' password='xxx' server='server2'; /* 根据服务器资源定义对应数量的会话 */
- 修改Data Step,按规则分配任务到不同会话:
data _null_; set process_table; /* 按index取模分配会话,示例为2个会话 */ sess = cats('sess', mod(index, 2)+1); call execute(cats('rsubmit ', sess, ';')); call execute('%create_table_type_a('||table||')'); call execute('endrsubmit;'); run;
不同远程会话会同时执行各自的表处理任务,实现并行效果。
方案三:Job Flow调度并行任务
将单表处理逻辑封装为独立SAS程序,通过SAS任务调度工具(如SAS Enterprise Guide任务流)读取process_table生成并行任务队列,设置多任务同时执行。
注意事项
- 并行处理需确保服务器有充足的CPU、内存资源,避免资源竞争导致性能下降。
- 若处理的表存储在共享存储设备,需确认存储系统支持并发读写,避免IO瓶颈。
内容的提问来源于stack exchange,提问作者walves

