5

如何以最佳方式在 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

4 回答 4

6

您的方法将导致内存问题。最快的方法是[在大卫发表评论后编辑查询以处理空场景]:

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 中。如果它滑入全局临时区域,此查询可能会变慢,但随后需要数据库调整。我认为没有比这更快的了。

关于 Query 使用内存的更多细节:

每个查询都有自己的 PGA [程序全局区域],基本上是每个查询可用的 RAM。如果此区域不足以返回查询结果,则 SQL 引擎开始使用像硬盘一样的 Golabl 临时表空间,并且查询开始变慢。如果查询需要的数据太大,以至于临时区域都不够用,那么就会出现表空间错误。

因此,请始终设计查询,使其保留在 PGA 中,否则它是一个危险信号。

于 2013-08-24T03:17:48.797 回答
2

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

insert into dtr_debtors1(SSN)
select level from dual connect by level <= 1000000;
于 2013-08-24T03:18:37.347 回答
0

尝试删除在表上创建的所有索引,然后尝试使用select查询插入。您可以试试这个链接,它可以帮助您将数百万行快速插入数据库。

于 2013-08-24T03:19:44.040 回答
0

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

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

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

4) 使用SQL LOADER实用程序。

于 2019-12-01T13:55:23.787 回答