我試圖儘可能快地將記錄從一個表複製到另一個表。Oracle BULK FETCH和FORALL插入時的性能問題
目前,我有一個簡單的遊標循環類同此:
FOR rec IN source_cursor LOOP
INSERT INTO destination (a, b) VALUES (rec.a, rec.b)
END LOOP;
我想加快速度是超級快,所以我想一些批量操作(本體FETCH,那麼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倍。
我在這裏錯過了一個瓶頸嗎?
對於100,000行,即使使用批量插入,也需要大約300(!)秒 – Will 2010-10-09 00:17:27
是否有原因在SELECT中有ORDER BY?對100,000行進行排序可能相當昂貴,而且似乎沒有必要。另外,您的%NOTFOUND檢查需要在FORALL之後發生 - 否則,如果您在上次迭代中讀取的行少於10,000行,則不會插入這些行。 – 2010-10-09 00:29:19
謝謝!我將刪除順序,但我不認爲它會讓我相當的速度即時通訊尋找...我會嘗試進行tkprof分析並稍後更新。很好的捕獲%NOTFOUND – Will 2010-10-09 03:12:13