我试图解决的问题:
我有一个work.testData包含 8 列和大约 100 万行的 SAS 数据集(在工作库中)。所有列都是文本(即没有数字数据)。此 SAS 数据集的文件大小约为 100 MB。我的目标是将整个 SAS 数据集解析为 Oracle。即有点像从 SAS 平台到 Oracle 平台的 SAS 数据集的“复制和粘贴”。这背后的基本原理是,每天,Oracle 中的这个表都会被 SAS 中的表“替换”,这将启用下游 Oracle 流程。
我解决问题的方法:
Oracle 中的一次性初始设置:
testData,其表结构与 SAS dataset 几乎相同testData。(即相同的表名、相同的列数、相同的列名等)。不断重复的过程:
示例代码
Oracle 中的一次性初始设置:
步骤 1:在 Oracle SQL Developer 中运行此 Oracle SQL 脚本(为表 testData 创建表结构。从 0 行数据开始。)
DROP TABLE testData;
CREATE TABLE testData
(
NODENAME VARCHAR2(64) NOT NULL,
STORAGE_NAME VARCHAR2(100) NOT NULL,
TS VARCHAR2(10) NOT NULL,
STORAGE_TYPE VARCHAR2(12) NOT NULL,
CAPACITY_MB VARCHAR2(11) NOT NULL,
MAX_UTIL_PCT VARCHAR2(12) NOT NULL,
AVG_UTIL_PCT VARCHAR2(12) NOT NULL,
JOBRUN_START_TIME VARCHAR2(19) NOT NULL
)
;
COMMIT;
Run Code Online (Sandbox Code Playgroud)
不断重复的过程:
步骤 2、3 和 4:在 SAS 中运行此 SAS 代码
******************************************************;
******* On-going repeatable process starts here ******;
******************************************************;
*** Step 2: Trancate the temporary Oracle transaction dataset;
proc sql;
connect to oracle (user=XXX password=YYY path=ZZZ);
execute (
truncate table testData
) by oracle;
execute (
commit
) by oracle;
disconnect from oracle;
quit;
*** Step 3: Assign Oracle DB as a libname;
LIBNAME ora Oracle user=XXX password=YYY path=ZZZ dbcommit=100000;
*** Step 4: Insert data from SAS to Oracle;
PROC SQL;
insert into ora.testData
select NODENAME length=64,
STORAGE_NAME length=100,
TS length=10,
STORAGE_TYPE length=12,
CAPACITY_MB length=11,
MAX_UTIL_PCT length=12,
AVG_UTIL_PCT length=12,
JOBRUN_START_TIME length=19
from work.testData;
QUIT;
******************************************************;
**** On-going repeatable process ends here *****;
******************************************************;
Run Code Online (Sandbox Code Playgroud)
我的方法的限制/问题:
Proc SQL 步骤(将 100 MB 的数据从 SAS 传输到 Oracle)需要大约 5 个小时才能执行 - 作业运行时间太长!
问题:
有没有更明智的方法来执行从 SAS 到 Oracle 的数据传输?(即从 SAS 更新 Oracle 表)。
首先,如果有必要,您可以从 SAS 进行删除/重新创建。我不会每次都删除并重新创建 - 截断似乎更容易获得相同的结果 - 但如果您有其他原因,那就没问题了;但无论哪种方式,您都可以使用execute (truncate table xyz) from oracle或类似于丢弃,使用直通连接。
其次,假设表上没有约束或索引 - 这似乎很可能是因为您正在删除和重新创建它 - 您可能无法改进这一点,因为它可能基于网络延迟。但是,您应该在连接设置中查看一个区域(您没有提供):SAS 提交数据的频率。
有两种方法可以控制它,DBCOMMMIT设置和BULKLOAD设置。前者控制执行提交的频率(因此如果DBCOMMIT=100每 100 行执行一次提交)。更频繁的提交 = 如果发生随机故障,丢失的数据更少,但执行速度要慢得多。DBCOMMIT 默认为 0 for PROC SQL INSERT,这意味着只进行一次提交(假设没有错误的最快选项),因此除非您覆盖它,否则这不太可能有帮助。
批量加载可能是我的建议;使用 SQLLDR 加载您的数据,即,它将整个位分批处理到 Oracle,然后说“请加载这个,谢谢”。它只适用于某些设置和某些类型的查询,但它应该在这里工作(取决于其他条件 - 阅读上面的文档页面)。
如果您使用 BULKLOAD,那么您可能会遇到网络延迟问题。100 MB 的 5 小时似乎很慢,但我在我(相对较短的)一天中看到了各种各样的事情。如果 BULKLOAD 不起作用,我可能会引入 Oracle DBA 并让他们解决此问题,从 .csv 文件和 SQL*LDR 命令文件开始(这应该与 SAS 对 BULKLOAD 所做的基本相同);他们应该知道如何解决这个问题,并且至少能够监控数据库本身的性能。如果此处存在问题的其他表存在限制(即,根据您的插入或其他内容过于频繁地重新计算自己的其他表),他们应该能够找出并推荐解决方案。
您可以查看PROC DBLOAD,它有时比 SQL 中的插入更快(尽管总而言之不应该如此,并且是一个不再使用太多的“旧”过程)。您还可以考虑是否可以避免执行完全刷新和填充(即,是否有一种方法可以通过网络传输更少的数据),或者甚至只是缩小列大小。
| 归档时间: |
|
| 查看次数: |
6946 次 |
| 最近记录: |