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

Posted

技术标签:

【中文标题】在 Oracle 中插入一百万行的最快方法【英文标题】:Fastest way to insert a million rows in Oracle 【发布时间】:2013-08-24 03:07:27 【问题描述】:

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

【问题讨论】:

我不建议为此使用光标。因为光标会降低您的性能。 查看link 【参考方案1】:

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

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 中,否则它是一个危险信号。

【讨论】:

这个查询不会使用临时表空间,它会先以ORA-30009: Not enough memory for CONNECT BY operation 失败。这有点奇怪,因为您可以通过alter session set workarea_size_policy=manual;alter session set sort_area_size=&lt;large number&gt;; 解决错误。显然不是所有的“排序”都可以使用临时表空间。 如果 dtr_debtors1 为空,那么您将在表中插入空值。使用 Coalesce(max(ssn),0)。【参考方案2】:

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

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

【讨论】:

【参考方案3】:

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

【讨论】:

【参考方案4】:

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

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

3) 另一种方法INSERT INTO &lt;tb_nm&gt; SELECT

4) 使用SQL LOADER 实用程序。

【讨论】:

以上是关于在 Oracle 中插入一百万行的最快方法的主要内容,如果未能解决你的问题,请参考以下文章

BigQuery 更快地插入数百万行的方法

如何检查/更新数据库中包含大约百万行的列?

当有大量数据[超过一百万行] [重复]时,改进 R 中的循环以提高时间效率

写了一百万行代码是什么体验?

在 MySQL 中计算特定日期之间数百万行的最佳方法

一百万个结构数组,根据其中一项值排序,用双链表还是数组排序效率更好,请给出最快C或C++算法代码。