【发布时间】:2020-05-10 19:00:23
【问题描述】:
我正在将字符串解析为逗号分隔并将它们插入到全局表中。插入大约 5k 条记录时性能很好,如果插入记录大约 40k+ 则性能很差。全局表只有一列。我认为使用 bulk fetch 和 forall 会提高性能,但到目前为止还不是这样。如何在插入查询下方重写或任何其他可以实现插入大记录的方式?帮助将不胜感激。我通过自己运行插入查询进行了测试,如果数据量很大,则需要很长时间来处理。
//large string
emp_refno in CLOB;
CREATE OR replace PROCEDURE employee( emp_refno IN CLOB ) AS
c_limit PLS_INTEGER := 1000;
CURSOR token_cur IS
WITH inputs(str) AS
( SELECT to_clob(emp_refno)
FROM dual ),
prep(s,n,token,st_pos,end_pos ) AS
(
SELECT ','|| str || ',',-1,NULL,NULL,1
FROM inputs
UNION ALL
SELECT s, n + 1,substr(s, st_pos, end_pos - st_pos),
end_pos + 1,instr(s, ',', 1, n + 3)
FROM prep
WHERE end_pos != 0
)
SELECT token
FROM prep
WHERE n > 0;
TYPE token_t
IS
TABLE OF CLOB;
rec_token_t TOKEN_T;
BEGIN
OPEN token_cur;
LOOP
FETCH token_cur bulk collect
INTO rec_token_t limit c_limit;
IF rec_token_t.count > 0 THEN
forall rec IN rec_token_t.first ..rec_token_t.last
INSERT INTO globaltemp_emp
VALUES ( rec_token_t(rec) );
COMMIT;
END IF;
EXIT
WHEN rec_token_t.count = 0;
END LOOP;
OPEN p_resultset FOR
SELECT e.empname,
e.empaddress,
f.department
FROM employee e
join department f
ON e.emp_id = t.emp_id
AND e.emp_refno IN
(
SELECT emp_refno
FROM globaltemp_emp) //USING gtt IN subquery
END;
【问题讨论】:
-
尝试在循环结束后移动提交,而不是在循环内。
-
@Kumar 我尝试在循环后移动提交,但性能没有提高。被这个性能问题困扰
-
这串 EMP REFNO 来自哪里?有什么东西把它们串联起来了,从那里接近它可能会更好。
-
@APC emp_refno 来自 java。我将它们解析为逗号分隔的字符串到控制器并将它们发送到 proc。像 Map
listemp = new Hashmap(): listemp.put("emp_refno", delemitemp_refno");任何建议在这里可以做什么 -
在其他任何事情之前,您应该先确定
select是慢还是insert。更改过程以执行相同的操作,除了insert,并检查所需的运行时间。
标签: sql oracle performance plsql