我正在使用Oracle版本> 10gR2中。 我有一张有2000万条记录的桌子。我想在将它们导出到文件之前处理所有记录,但是这样做的速度非常慢。
你有什么建议吗?以下是我的代码:
declare
l_temp_detail clob := null;
icount number:=0;
cursor c_test is
select /*+ PARALLEL(12) */ *
from test_table t;
TYPE t_test IS TABLE OF test_table%ROWTYPE INDEX BY PLS_INTEGER;
l_test_items t_test;
BEGIN
l_temp_detail := '';
OPEN c_test;
LOOP
FETCH c_test
BULK COLLECT INTO l_test_items LIMIT 25000;
EXIT WHEN l_test_items.COUNT = 0;
FOR i in l_test_items.first .. l_test_items.last LOOP
icount := icount+1;
--doing business here
l_temp_detail := ....
END LOOP;
dbms_output.put_line(to_char(icount));
END LOOP;
CLOSE c_test;
END;
答案 0 :(得分:0)
一些事情。仅使用您需要的test_table
列。根据您的需要,您似乎只需要来自test_table
的一些列和有限的记录集。你不会在一起连接2000万条记录。
此外,由于表格很大,您可能需要检查是否存在任何分区和索引。使用特定partition
和右index
将增强查询执行时间。
答案 1 :(得分:0)
Parallel table functions启用并行查询和并行程序处理。
示例表和数据。
drop table test_table;
create table test_table(a number);
insert into test_table select level from dual connect by level <= 1000000;
commit;
退货类型(即使您不关心结果,也需要退货)
create or replace type number_nt is table of number;
并行管道列表功能
--The syntax is very picky if you want to enable parallelism.
create or replace function f(p_cursor in sys_refcursor) return number_nt
pipelined parallel_enable(partition p_cursor by any) is
l_temp_detail clob := null;
icount number:=0;
type t_test is table of test_table%rowtype index by pls_integer;
l_test_items t_test;
begin
LOOP
FETCH p_cursor
BULK COLLECT INTO l_test_items LIMIT 25000;
EXIT WHEN l_test_items.COUNT = 0;
FOR i in l_test_items.first .. l_test_items.last LOOP
icount := icount+1;
--doing business here
--l_temp_detail := ....
END LOOP;
dbms_output.put_line(to_char(icount));
END LOOP;
CLOSE p_cursor;
pipe row (icount);
end;
/
查询和结果
--You may want to SUM() to get a total count.
--These aren't the results you care about, but they help show the distribution.
select column_value
from table(f(cursor(select /*+ parallel(12) */ * from test_table)));
COLUMN_VALUE
------------
124080
116160
65340
58080
79860
65340
60060
79860
59400
46960
116160
128700
答案 2 :(得分:0)
我实际上没有在10g上测试过这个,但是在Oracle9上处理plsql表中的大量记录比处理单个值表的效率要低10倍。
所以 - 如果您将代码从“记录表”重构为“表记录”,您可能会看到显着的改进。你实际上并不需要将各个表捆绑在一个记录中 - 为了清楚起见,我只是喜欢它。
E.g。
declare
type tName is table of mytable.name%type index by pls_integer;
type tAddress is table of mytable.address%type index by pls_integer;
type tPerson is record (
name tName;
address tAddress;
);
person tPerson;
begin
open somecursor;
loop
fetch somecursor bulk collect into person.name, person.address limit 25000;
--
-- processeing
--
exit when ...
end loop;
close somecursor;
end;
我不能保证这肯定会解决您的问题 - 这取决于您在“处理”中对数据的实际操作 - 例如,在plsql中花费了多少时间以及在SQL中花了多少时间做dml。