2013-08-24 42 views
5

如何在以下步骤中以最佳方式在Oracle中插入超过一百万行?如果我将FOR循环增加到一百万行,它会挂起。在Oracle中插入一百万行的最快方法

create or replace procedure inst_prc1 as 
    xssn number; 
    xcount number; 
    l_start Number; 
    l_end Number; 
    cursor c1 is select max(ssn)S1 from dtr_debtors1; 

Begin 
    l_start := DBMS_UTILITY.GET_TIME; 
    FOR I IN 1..10000 LOOP 
    For C1_REC IN C1 Loop 
     insert into dtr_debtors1(SSN) values (C1_REC.S1+1); 
    End loop; 
    END LOOP; 
    commit; 
    l_end := DBMS_UTILITY.GET_TIME; 
    DBMS_OUTPUT.PUT_LINE('The Procedure Start Time is '||l_start); 
    DBMS_OUTPUT.PUT_LINE('The Procedure End Time is '||l_end); 
End inst_prc1; 
+0

我不建议使用光标。光标会降低你的表现。 –

+0

选中此链接(http://www.orafaq.com/wiki/Oracle_Row_Generator_Techniques) – haki

回答

5

您的方法会导致内存问题。最快的方式将是[查询大卫的评论后编辑照顾空场景]:

insert into dtr_debtors1(SSN) 
select a.S1+level 
    from dual,(select nvl(max(ssn),0) S1 from dtr_debtors1) a 
connect by level <= 10000 

一个选择Insert是一切都保持在RAM中的最快方法。 如果该查询滑入全局临时区域,则该查询可能会变慢,但需要进行数据库调整。我认为没有比这更快的东西。

很少内存使用的详细信息通过查询:

每个查询都会有自己的PGA [程序全局区],它基本上是可用RAM每个查询。如果这个区域不足以返回查询结果,那么SQL引擎开始使用Golabl临时表空间,这就像硬盘一样,查询开始变慢。如果查询所需的数据非常庞大,即使临时区域不够用,您也会出现表空间错误。

因此,总是设计查询,以便它停留在PGA,否则它将成为红旗。

+1

该查询不会使用临时表空间,它会因'ORA-30009:首次没有足够的内存用于CONNECT BY操作'而失败。这很奇怪,因为你可以通过'alter session set workarea_size_policy = manual;'和'alter session set sort_area_size = ;来解决错误。显然不是所有的“排序”都可以使用临时表空间。 –

+0

如果dtr_debtors1是空的,那么你要插入空值到表中。使用合并(max(ssn),0)。 –

2

一次插入一行,单循环内的单个insert语句很慢。最快的方法是使用insert-select,如下所示,它会生成一百万行和批量插入。

insert into dtr_debtors1(SSN) 
select level from dual connect by level <= 1000000; 
+0

这不是正确的解决方案。查看我的回答 – Lokesh

+0

感谢lokiIts为此链接工作 – user1016594

0

尝试删除你的桌子上创建的所有索引,然后尝试使用select查询插入。你可以尝试这个链接,这将帮助你在inserting millions of rows快速进入你的数据库。

+0

-1。过时的,不相关的和可疑的内容。 –

相关问题