我正在尝试将数据从oracle加载到sql server(很抱歉之前不写这个)
我有一个表(实际上是一个包含来自不同表的数据的视图),至少有100万条记录。我设计我的软件包的方式使我具有业务逻辑功能,并直接在select查询中调用它们。
例如:
X1(id varchar2)
x2(id varchar2, d1 date)
x3(id varchar2, d2 date)
Select id, x, y, z, decode (.....), x1(id), x2(id), x3(id)
FROM Table1
注意:我的表有20列,我在至少6-7列上调用5个不同的函数。 并且一些函数比较传递给审计表的参数并执行逻辑
如何改善查询的效果,或者有更好的方法来实现这一目标
我尝试在C#代码中执行此操作,但初始选择的记录对于数据集来说足够大,而且我得到了外部存储异常。
我的函数确实选择然后执行逻辑,例如:
Function(c_x2, eid)
Select col1
into p_x1
from tableP
where eid = eid;
IF (p_x1 = NULL) THEN
ret_var := 'INITIAL';
ELSIF (p_x1 = 'L') AND (c_x2 = 'A') THEN
ret_var:= 'RL';
INSERT INTO Audit
(old_val, new_val, audit_event, id, pname)
VALUES
(p_x1, c_x2, 'RL', eid, 'PackageProcName');
ELSIF (p_x1 = 'A') AND (c_x2 = 'L') THEN
ret_var := 'GL';
INSERT INTO Audit
(old_val, new_val, audit_event, id, pname)
VALUES
(p_x1, c_x2, 'GL', eid, 'PackgProcName');
END IF;
RETURN ret_var;
答案 0 :(得分:4)
我正在获得每一行并表演 C#中的逻辑然后插入
如果可能,请从SELECT中输入:
INSERT INTO YourNewTable
(col1, col2, col3)
SELECT
col1, col2, col3
FROM YourOldTable
WHERE ....
这将比单个查询更快地运行 ,然后循环结果集并为每一行设置INSERT。
对OP问题编辑编辑:
您应该能够在查询中将函数调用替换为纯SQL。使用LEFT JOIN tableP模仿“initial”,可以使用CASE计算“RL”或“GL”。
编辑基于OP最近的评论:
因为您正在将数据从Oracle加载到SQL Server中,所以我会这样做:大多数人可以提供帮助而不会再次阅读此问题,因此请打开一个新问题:1)您需要要将数据从Oracle(版本)加载到SQL Server版本2),目前您正在从处理C#中每一行的一个查询加载它并将其插入SQL Server,这很慢。以及所有其他细节。有更好的方法可以将数据批量加载到SQL Server中。至于这个问题,你可以接受一个答案,回答你自己在哪里解释你需要提出一个新问题,或者只是让它不被接受。
答案 1 :(得分:2)
我的建议是你不使用函数,然后在其他SELECT语句中调用它们。这样:
SELECT t.id, ...
x1(t.id) ...
FROM TABLE t
......相当于:
SELECT t.id, ...
(SELECT x.column FROM x1 x WHERE x.id = t.id)
FROM TABLE t
封装在SQL中不起作用,就像使用C#/ etc时一样。虽然该方法使维护更容易,但性能会受到影响,因为子选择将针对返回的每一行执行。
更好的方法是在SELECT中更新支持函数以包含连接标准(IE:“where x.id = t.id
”,因为缺少真实的):
SELECT x.id
x.column
FROM x1 x
...所以你可以把它用作JOIN:
SELECT t.id, ...
x1.column
FROM TABLE t
JOIN (SELECT x.id,
x.column
FROM MY_PACKAGE.x) x1 ON x1.id = t.id
我更喜欢为了维护而必须将函数逻辑合并到查询中,但有时它无法帮助。
答案 2 :(得分:1)
就个人而言,我会创建一个SSIS导入来执行此任务。使用abulk插入可以大大提高速度,SSIS可以在批量插入后处理功能部分。
答案 3 :(得分:0)
在桌面上创建一个已排序的整数。
Introduction to SQL Server Indizes,其他RDBMS类似。
编辑问题以来编辑:
使用视图甚至更不理想,尤其是从查询单行时。我认为你的“业务功能”实际上就像存储过程一样?
正如其他人所说,在SQL中总是以set为基础。我以为你已经这样做了,因此我的提示开始使用索引。
答案 4 :(得分:0)
一些提示:
INSERT
变慢但SELECT
快。答案 5 :(得分:0)
首先,您需要找到性能问题的实际位置。然后你可以试着解决它。
视图的性能如何?执行视图需要多长时间 没有任何函数调用?尝试运行命令
它的表现如何?需要1分钟还是1小时?
create table the_view_table as select * from the_view;
这些功能的表现如何?根据描述,您正在进行大约500万次函数调用。他们最好效率很高!定义为deterministic
的函数也是如此。如果使用deterministic
关键字定义函数,则Oracle有可能优化一些调用。
有没有办法减少函数调用次数?一旦评估了视图并且可以获得数百万行数据,就会调用该函数。但是来自查询最高级别的所有输入值?可以将函数调用嵌入到较低级别的视图中。请考虑以下两个查询。哪个会更快?
select f.dim_id, d.dim_col_1, long_slow_function(d.dim_col_2) as dim_col_2 from large_fact_table f join small_dim_table d on (f.dim_id = d.dim_id)
select f.dim_id, d.dim_col_1, d.dim_col_2 from large_fact_table f join ( select dim_id, dim_col_1, long_slow_function(d.dim_col_2) as dim_col_2 from small_dim_table) d on (f.dim_id = d.dim_id)
理想情况下,第二个查询应该运行得更快,因为它调用函数的次数更少。
性能问题可能出在上述任何一个地方,在您调查问题之前,很难知道在哪里指导您的调优工作。