使用批量插入在oracle中的表之间移动大数据

时间:2013-11-07 14:32:29

标签: sql oracle plsql oracle11g bulkinsert

我想将100万行数据移动到另一个表中。我正在使用查询:

insert into Table1
select * from Table2;

在我的PL / SQL函数中。但这种方式太慢了。

如何使用批量插入方法执行此操作?

  • 源表和目标表具有相同的结构。
  • 表有散列分区和1索引。

2 个答案:

答案 0 :(得分:4)

忘记批量插入。因为插入到select中是您可以加载的最佳批量。 最快的是禁用索引(标记它们不可用)并在SINGLE中执行此操作 插入:

insert /*+ append */ into TARGET
select COLS
  from SOURCE;

commit;

并使用UNRECOVERABLE(甚至可能是并行)重建索引。

PS:如果表是分区的(源和目标,你甚至可以使用并行插入)

关注:

检查以下选择的性能

SELECT    /*+ PARALLEL(A 4)
            USE_HASH(A) ORDERED */
      YOUR_COLS
FROM
      YOUR_TABLE A
WHERE
      ALL_CONDITIONS;

如果更快那么

INSERT   /*+ APPEND */
     INTO
      TARGET
    SELECT /*+ PARALLEL(A 4)
            USE_HASH(A) ORDERED */
          YOUR_COLS
    FROM
          YOUR_TABLE A
    WHERE
          ALL_CONDITIONS;

答案 1 :(得分:1)

使用批量收集

转换为集合和批量处理会增加代码的数量和复杂性。但是,如果您需要大幅提升性能,那么这种提升是完全合理的。

集合,PL/SQL 表的演变,它允许我们作为一个单元同时操作许多变量。集合与 Oracle 8i 引入的两个新特性 BULK_COLLECT 和 FORALL 相结合,可以显着提高 PL/SQL 中数据操作代码的性能。

CREATE OR REPLACE PROCEDURE test_proc (p_array_size IN PLS_INTEGER DEFAULT 100)
IS
TYPE ARRAY IS TABLE OF all_objects%ROWTYPE;
l_data ARRAY;

CURSOR c IS SELECT * FROM all_objects;

BEGIN
    OPEN c;
    LOOP
    FETCH c BULK COLLECT INTO l_data LIMIT p_array_size;

    FORALL i IN 1..l_data.COUNT
    INSERT INTO t1 VALUES l_data(i);

    EXIT WHEN c%NOTFOUND;
    END LOOP;
    CLOSE c;
END test_proc;