3

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

insert into Table1
select * from Table2;

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

如何使用批量插入方法做到这一点?

  • 源表和目标表具有相同的结构。
  • 表具有哈希分区和 1 个索引。
4

2 回答 2

5

忘记批量插入。因为插入到 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;
于 2013-11-07T14:41:06.263 回答
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;
于 2021-07-03T22:18:35.973 回答