2010-03-23 55 views
0

昨天我问了一个question,得到的答案但没有回答主要问题。我想减少执行MINUS操作所需的时间。追加到oracle中的游标

现在,我正在考虑在5000个块中做MINUS操作,将每个迭代结果附加到游标并最终返回游标。 我有以下几点:

V_CNT   NUMBER :=0; 
V_INTERVAL  NUMBER := 5000; 

begin 
    select count(1) into v_cnt from TABLE_1 
while (v_cnt > 0) 
loop 
open cv_1 for 
    SELECT A.HEAD,A.EFFECTIVE_DATE, 
    FROM TABLE_1 A 
    WHERE A.TYPE_OF_ACTION='6' AND A.EFFECTIVE_DATE >= ADD_MONTHS(SYSDATE,-15) 
    AND A.ROWNUM <= V_INTERVAL 
    MINUS 
    SELECT B.head,B.EFFECTIVE_DATE, 
    FROM TABLE_2 B 
    AND B.ROWNUM <= V_INTERVAL 

V_CNT := V_CNT - V_INTERVAL; 
END LOOP; 
end; 

但是,当你看到......在每次迭代光标被覆盖。我怎样才能更改代码,以便在每次迭代中追加游标而不是覆盖?

+0

用pl/sql执行直连sql是非常困难的。如果操作在直接sql中很慢,它很可能在pl/sql中保持缓慢。 – 2010-03-23 18:47:07

+0

我明白这一点。但是当我以5000的批次执行时,它非常快。 – Omnipresent 2010-03-23 18:48:38

+0

分批5000个查询需要4秒,而8个,所以我很好。在第二次迭代中再次需要4秒...等等。基本上每个连续的查询不应超过8秒。 – Omnipresent 2010-03-23 18:50:51

回答

0

这不是游标的工作方式,你必须将这些值存储在某种集合中。

您当前的查询从Table_1获取5000个随机行,并删除从Table_2中选择的5000个随机行中也存在的行。


您是否尝试过不使用MINUS

据我了解查询,它应该产生相同的,因为这一个:

Select a.head, a.effective_date, 
From table_1 a 
Left Join table_2 b On (b.head = a.head And b.effective_date = a.effective_date) 
Where a.type_of_action='6' And a.effective_date >= ADD_MONTHS(SYSDATE,-15) 
    And b.head Is Null; 

有一个复合指数TABLE_1 (type_of_action, head, effective_date)TABLE_2 (head, effective_date)应该帮助你的表现。

+0

嗯5000是随机的,但最终我的目标是覆盖整个表的权利?它呢? 您提供的左加入没有返回任何结果,而负号返回60538结果.. – Omnipresent 2010-03-23 19:02:41

+0

从您的exp ... rownum方法听起来不错,或者随机选择5000行..它不会与rownum一致?我可以考虑将值放入集合中,并最终将它们插入到光标中 – Omnipresent 2010-03-23 19:06:31

+0

我想我的帖子应该回答,为什么在这两种方法中获得不同的结果。 – 2010-03-23 19:08:57

1

您尚未明确说明要求。 所以,我假设你想在两个表A,B上做一个减法。 即你想在A中找到不在B中的元组。

假设这样,你写的逻辑是不完全正确,因为您正在对相应的(5000长度)批次A和B执行MINUS。

例如:您的逻辑将返回表A中第4000行的元组,例如第6000个表B的行。

我建议你使用left-outer join来完成你的需要。 (和Peter Lang的帖子一样)。 这应该足以满足您的性能要求,我想。