与程序/功能中的有效DML相关的问题

时间:2011-12-01 18:51:53

标签: performance oracle plsql oracle10g dml

在执行DML时,我有两个关于PL / SQL脚本性能的问题。当然EXECUTE IMMEDIATE是最慢的,这就是为什么我们有forallbulk插入等等。我的问题是

  1. 我必须操纵3个不同的表中的数据。 Table1(插入数据),Table2(更新数据)和Table3删除数据。所有这些都将基于使用游标获取的值来完成。问题是这里会更有效率吗?
    • 将每个语句放在单独的Forall块中?即
  2. fetch cursor
    loop
       forall loop for table 1
       forall loop for table 2
       forall loop for table 3
    end loop
    

    OR

    • 一个全局循环并在该循环中执行这些陈述,即
    fetch cursor loop
        for i IN array.count 
        loop
           3 statements for DML
        end loop end loop
    

    现在我的第二个问题

    1. 在循环中删除记录的有效方法是什么?我通过游标获取要删除的记录的值。现在删除它们的有效方法是什么?
    2. P.S: 执行我的格式

1 个答案:

答案 0 :(得分:4)

最有效的方法是编写三个SQL语句,假设从游标中获取的数据在过程运行的时间段内是稳定的

INSERT INTO table1( list_of_columns )
  <<your SELECT statement>>

UPDATE table2
   SET (<<list of columns>>) = (<<your SELECT statement joined to table2>>)
 WHERE EXISTS( <<your SELECT statement joined to table2>> );

DELETE FROM table3
 WHERE EXISTS( <<your SELECT statement joined to table3>> );

如果SELECT语句可能会在三个DML语句中的每一个中返回不同的结果,那么接受使用游标的性能损失,将数据批量收集到PL / SQL集合以及循环中是有意义的。在集合上,以确保一致的结果。如果这就是你正在做的事情,那么拥有三个FORALL语句会更有效率,因为这会减少SQL和PL / SQL引擎之间的上下文转换。

  

在循环中删除记录的有效方法是什么?我通过游标获取要删除的记录的值。现在删除它们的有效方法是什么?

我不确定我理解这个问题。你是不是就像FORALLINSERT

一样进行UPDATE循环
FORALL i IN l_array.first .. l_array.last
  DELETE FROM some_table
   WHERE some_key = l_array(i);

或者你问的是另一个问题?