在Oracle中插入一百万行的最快方法

时间:2013-08-24 03:07:28

标签: oracle11g

如何以最佳方式在Oracle中插入超过一百万行以进行以下处理?如果我将FOR循环增加到一百万行,它就会挂起。

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;

4 个答案:

答案 0 :(得分:5)

您的方法会导致内存问题。最快的方式是[在David的评论之后编辑查询以处理空方案]:

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 

选择插入是最快的方法,因为所有内容都保留在RAM中。 如果此查询进入全局临时区域但是需要进行数据库调整,则此查询可能会变慢。我认为没有比这更快的东西。

有关查询内存使用的更多详细信息:

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

所以总是设计查询,以便它保持在PGA中,否则它是一个红旗。

答案 1 :(得分:2)

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

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

答案 2 :(得分:0)

尝试删除在表上创建的所有索引,然后尝试使用select查询进行插入。您可以尝试使用此链接,它可以帮助您inserting millions of rows快速进入您的数据库。

答案 3 :(得分:0)

1)如果要使用PL / SQL插入,请使用BULK COLLECT INTO,要插入DML,请使用BULK BIND FOR ALL

2)在SQL多重插入中,使用INSERT ALL语句。

3)另一种方法INSERT INTO <tb_nm> SELECT

4)使用SQL LOADER实用程序。