我想将 100 万行数据移动到另一个表中。我使用查询:
insert into Table1
select * from Table2;
在我的 PL/SQL 函数中。但是这种方式太慢了。
如何使用批量插入方法做到这一点?
- 源表和目标表具有相同的结构。
- 表具有哈希分区和 1 个索引。
我想将 100 万行数据移动到另一个表中。我使用查询:
insert into Table1
select * from Table2;
在我的 PL/SQL 函数中。但是这种方式太慢了。
如何使用批量插入方法做到这一点?
忘记批量插入。因为插入到 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;
使用批量收集
转换为集合和批量处理会增加代码的数量和复杂性。但是,如果您需要大幅提升性能,那么这种提升是合理的。
集合是 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;