【发布时间】:2018-08-29 20:35:49
【问题描述】:
目前,我正在尝试通过数据库链接批量插入大量数据(约 500,000 行)。我正在从物化视图中获取数据。我打算添加索引,但在某处读到这实际上会减慢进程。插入行后,我将获取唯一 ID 并将它们插入到标记表中,以便将它们标记为“已插入”并且不会再次插入。然而,这个过程现在已经停滞了大约 30 分钟。有一个更好的方法吗? (以下是我的代码)。
create or replace PROCEDURE SEND_DATA
IS
CURSOR cursora
IS
SELECT DISTINCT unique_id_1
FROM mv_1;
CURSOR cursorb
IS
SELECT DISTINCT unique_id_2
FROM mv_2;
ca cursora%ROWTYPE;
cb cursorb%ROWTYPE;
sent_flag NUMBER(10);
BEGIN
SELECT flag_id
INTO sent_flag
FROM flag f
WHERE f.flag_tx = 'SENT';
---
Delete FROM TABLE1@db1
WHERE to_date(to_char(LOCAL_TIMESTAMP,'mm/dd/yyyy'),'mm/dd/yyyy') || code in
(SELECT distinct to_date(to_char(LOCAL_TIME_TS,'mm/dd/yyyy'),'mm/dd/yyyy'), code FROM MV_1);
COMMIT;
Delete FROM TABLE1@db1
WHERE type || timestamp in (SELECT DATA_Type_TX || UTC_TS FROM MV_1);
COMMIT;
insert into TABLE1@db1(DATE, TYPE, VALUE, LAST_UPDATE, FLAG, LOCAL_TIMESTAMP)
SELECT DATA_DATE, NAME, VALUE, SYSDATE, null, LOCAL_TIME
FROM MV_2 A;
COMMIT;
OPEN cursora;
LOOP
FETCH cursora into ra;
EXIT WHEN cursora%NOTFOUND;
INSERT INTO flag(
SUBMIT_ID,
FLAG_ID,
CREATE_USER_ID,
CREATE_DT)
VALUES (
rdba.SUBMIT_ID,
SENT_FLAG,
'1',
sysdate);
END LOOP;
CLOSE cursora;
COMMIT;
---
EXCEPTION
WHEN OTHERS
THEN
NULL;
RAISE;
END SEND_DATA;
【问题讨论】:
-
不要循环插入。请改用
insert ... select -
使用循环/游标方法比批量插入有什么好处吗?
-
可怕的逐行方法总是比较慢(有些人称之为逐行缓慢)
-
逐行方法光标是否正确?不是批量插入? (对不起这个愚蠢的问题)
-
您的代码中没有“批量插入”。您需要将一批行提取到集合中,然后将 insert 与 FORALL 语句一起使用,以获得“批量选择/插入”功能。详情见这篇文章:On BULK COLLECT。但在您的情况下,最简单和最快的方法很简单:INSERT ... SELECT ... 语句。例如看这个问题:stackoverflow.com/questions/7323407/…