ORACLE PL / SQL包需要几个小时才能完成

时间:2014-02-08 07:53:32

标签: sql oracle plsql

我有一个Oracle包,其输入参数为开始日期sysdate-365,结束日期为sysdate + 90。它找到从sysdate-365到sysdate + 90的每个日期,这是455天,然后它为每个日期循环,从主表中获取记录再次循环基于主表数据,从其他表获取值,做一些逻辑并插入工作台。完成需要10个多小时。

我想过使用dbms_scheduler来运行包并行,因为DBA不推荐这样做。任何人都可以建议任何其他方式来提高性能吗?

代码段:

loop for date range
select some_data from master_table where master_date = cursor.date;


loop for 
select other_data from other_table where other_date = cursor.date
start with some_data 
connect by other_parent = prior other_child;


select count(*) into v1cnt from third_table where third_date = cursor.date and third_data=other_data; 

if v1cnt  > 0 then
select third_data into variable1 from third_table where third_date = cursor.date and third_data=other_data; 
else
variable1 = null;
end if;

select count(*) into v2cnt from fourth_table where third_date = cursor.date and fourth_data=other_data;

if v2cnt  > 0 then
select fourth_data into variable2 from fourth_table where third_date = cursor.date and fourth_data=other_data; 
else
variable2 := null;
end if;


do some other logic.


insert into working_table (variable1,variable2 ,cursor.date, fields from other logics);

end loop;
end loop;

1 个答案:

答案 0 :(得分:8)

这是一种称为Row By Agonizing Row(RBAR)的数据库编程风格。您可以看到,SQL是一种基于集合的语言,旨在在单个操作中处理大量行。通过将您的逻辑分解为一系列操作,每个操作一次只能处理一行,您已经引入了大量的开销。

现在,并行运行此程序可能会减少总体运行时间,但这会使总资源使用率变得更糟:您仍然会在所有RBAR处理中咀嚼CPU,而且还有额外的管理并行查询的开销。难怪你的DBA反对它。很遗憾他们没有就如何修复你的代码提出建议。

我们很难给你一个实际的解决方案,因为我们不知道“做其他一些逻辑”背后隐藏着什么逻辑。但是,您发布的所有代码都是纯SQL。因此应该可以用INSERT INTO ... SELECT ...替换所有PL / SQL。

实际的SELECT可能有点粗糙,可能需要子查询或WITH子句(find out more),但它将基于集合,并且可能比当前程序执行快几个数量级。如果您不知道如何编写复杂的查询,那么您应该点击DBA获取一些专家建议。