Sql server 在SAS中将大型数据集复制到服务器的最快方法 10月21日编辑
背景 存储在基于MS-SQL的服务器上的原始数据集(每天更改):Sql server 在SAS中将大型数据集复制到服务器的最快方法 10月21日编辑,sql-server,sas,processing-efficiency,memory-efficient,Sql Server,Sas,Processing Efficiency,Memory Efficient,背景 存储在基于MS-SQL的服务器上的原始数据集(每天更改):Sourcelib.Raw和LOCALexcel文件(保持不变) 我需要刷新位于targetlib中的数据集WANT。目前我有SQL代码在2-3分钟内完成这项任务。但是我想知道SAS是否可以做同样的事情,而处理时间不会增加太多 work.IMP大约有600万条记录,每条记录大约有50个字节 理想的方法应该是非常有效的,因为随着时间的推移,服务器上的原始数据集的大小将是惊人的巨大 无法一次建立目标文件,然后每天向其追加新数据。因为以前
Sourcelib.Raw
和LOCAL
excel文件(保持不变
)
我需要刷新位于targetlib
中的数据集WANT
。目前我有SQL代码在2-3分钟内完成这项任务。但是我想知道SAS是否可以做同样的事情,而处理时间不会增加太多
work.IMP
大约有600万条记录,每条记录大约有50个字节,然后每天向其追加新数据。因为以前的数据可能(甚至不太可能)有变化李>
按照@Joe的说法,我应该允许只使用proc compare
或data step
中的update
更新目标文件。这是我发布的一个相关问题
服务器上还有超过10GB的可用空间,这就足够了。我电脑的可用内存约为3.5GB(不确定是否重要)
由于服务器的体系结构,在MS-SQL中执行此操作非常高效。但我真的很想知道SAS是否能够处理这一问题(当服务器不太兼容时)
)work.IMP
。由于某些原因,每天只能以这种方式创建此文件。它不能
存储在服务器中李>
work.IMP
和一个原始数据集Sourcelib.RAW1
执行外部联接,以获得work.HAVE1
。请注意,work.IMP
已排序,但Sourcelib.RAW1
未排序。外部联接仅用于(根据某些条件)确定每个数据记录即,当a.COL1为“”时,则b.COL1,否则a.COL1以COL1结尾
您可以考虑使用<代码>工作来调整<代码> SoSeliB.RaW1/<代码> IMP < /C> > /P> PS1:@sparc_spread建议直接向服务器执行导入过程。但它不会比在
LOCAL
中执行有任何好处。这里的散列对象也没有帮助
然后,我将另一个原始数据集Sourcelib.RAW2
子集为work.temp
,然后排序
为work.HAVE2
。(Sourcelib.RAW2
中的数据大多不整齐。)
我通过使用proc append
(因为这两个表都很大)将work.HAVE1
,work.HAVE2
连接成work.HAVE
PS2:step3
中的排序是为了避免在step4
末尾进行排序。实际上,数据targetlib.WANT
不一定是有序的。但最好是这样
最后,我将work.HAVE
复制到服务器Targetlib.HAVE
李>
我在工作中做了大部分事情,只花了几分钟。但是step5
可能需要半个小时才能完成拷贝
根据@Joe的说法,这可能主要是由于与网络传输相关的原因<代码>即
最小化网络传输
问题
有什么方法可以改进步骤5
?或者对整个过程的任何修改都会提高性能?您可以使用PROC APPEND
高效地创建新数据集,而不仅仅是附加到现有数据集-因此,您可以使用它将步骤3和步骤4基本合并到以下内容中:
/* To fulfill requirement 4, delete existing Targetlib.HAVE */
PROC DELETE LIBRARY="Targetlib" DATA="HAVE";
RUN;
/* Targetlib.HAVE does not yet exist, the first APPEND will create it */
PROC APPEND BASE="Targetlib.HAVE" DATA="work.HAVE1";
RUN;
PROC APPEND BASE="Targetlib.HAVE" DATA="work.HAVE2";
RUN;
这至少可以节省一些时间,但这仍然不能解决你所有的问题。。。我有一些额外的问题,我已经在对这个问题的评论中提出了,我将根据这些问题尽可能地修改这个答案
更新1
这里有一种方法可以一步完成左连接和串联,并将结果立即写入targetlib
。我不能保证这会更快,但值得一试。我使用了键
和val
作为字段名,根据需要进行替换
PROC SQL _METHOD;
CREATE TABLE targetlib.HAVE
AS
SELECT
a.key ,
CASE WHEN MISSING (a.val) THEN b.val ELSE a.val END AS val
FROM
Sourcelib.RAW1 AS a
LEFT JOIN
IMP AS b
ON
a.key = b.key
UNION
SELECT
c.*
FROM
Sourcelib.RAW2 AS c
ORDER BY
key
;
QUIT;
RUN;
\u方法
是一种文档稀少的SAS功能,用于打印查询计划,请参阅。这可能会给你更多的洞察力。另外,我假设IMP
已经从Excel导入,并且它在WORK
中。实验看看将其导入targetlib
并将IMP作为b
替换为targetlib.IMP作为b
是否更快
由于您在Windows上,请在数据集名称之后尝试使用数据选项SGIO=YES
:例如,作为
的Sourcelib.RAW1变为作为
的Sourcelib.RAW1(SGIO=YES)。有关Windows SGIO和SAS的更多信息,请参阅和
一种可能更有效的方法是避免连接,而是使用散列对象:为散列对象和对象提供良好的文档。现在还不清楚这是否会更快-imp
有6万条记录,但以每条记录50字节的速度计算,大约是300 MB,这确实适合您的RAM。具有这么多条目的哈希表的性能在很大程度上取决于SAS的哈希算法。无论如何,下面是使用哈希对象的代码。在其中,我们假设在IMP
数据集中,val
字段已重命名为val2
DATA targetlib.HAVE (DROP = rc val2);
LENGTH val2 8. ;
IF (_N_ = 1) THEN DO;
DECLARE HASH h (DATASET: "IMP") ;
h.DEFINEKEY ('key');
h.DEFINEDATA ('val2');
h.DEFINEDONE ();
END;
SET
sourcelib.RAW1
sourcelib.RAW2
;
IF MISSING (val) THEN DO;
rc = h.find();
IF (rc = 0) THEN DO;
val = val2;
END;
END;
RUN;
PROC SORT DATA = targetlib.HAVE ; BY KEY ; RUN ;
试试看它是否更快。再次,使用SGIO
等,对IMP
的位置进行实验。最后的PROC SORT
可能会很昂贵;如果你之前排序的唯一原因是因为加入,那么跳过它
一般来说,SAS的方法应该是尽可能少地进行I/O操作,并找到从PROC
或DATA
步骤将多个操作组合成一次写入的方法
Cou