我正在尝试尽快将记录从一个表复制到另一个表。
目前我有一个类似的简单光标循环:
FOR rec IN source_cursor LOOP
INSERT INTO destination (a, b) VALUES (rec.a, rec.b)
END LOOP;
我想加快速度,所以我正在尝试一些BULK操作(BULK FETCH,然后是FORALL插入):
以下是批量选择/ forall插入的内容。
DECLARE
TYPE t__event_rows IS TABLE OF _event%ROWTYPE;
v__event_rows t__event_rows;
CURSOR c__events IS
SELECT * FROM _EVENT ORDER BY MESSAGE_ID;
BEGIN
OPEN c__events;
LOOP
FETCH c__events BULK COLLECT INTO v__event_rows LIMIT 10000; -- limit to 10k to avoid out of memory
EXIT WHEN c__events%NOTFOUND;
FORALL i IN 1..v__event_rows.COUNT SAVE EXCEPTIONS
INSERT INTO destinatoin
( col1, col2, a_sequence)
VALUES
( v__event_rows(i).col1, v__event_rows(i).col2, SOMESEQEUENCE.NEXTVAL );
END LOOP;
CLOSE c__events;
END;
我的问题是到目前为止我没有看到任何大的表现。根据我的阅读,它应该快10倍-100倍。
我在某处错过了瓶颈吗?
答案 0 :(得分:7)
您的代码对简单INSERT
+ SELECT
的唯一好处是您可以保存例外,而且(正如Justin指出的那样)您有一个无意义的ORDER BY
正在使它一大堆毫无意义的工作。然后,您没有任何代码可以对保存的异常做任何事情。
我只是将其作为INSERT
+ SELECT
实施。
答案 1 :(得分:0)
在编码本身需要之前,您不必不必要地使用循环。