2006 年 10 月 17 日, 星期二

plsql表比游标更快

在遇到使用游标嵌套循环时,由于我们需要在里层循环里open和close游标,这样重复很多次,导致性能会很低下。此时可以使用plsql来改善性能。
使用plsql,每个游标只需要open close一次。减少的时间不是一点两点。


下面的例子仅是简单的示范用法和性能对比,经过分别多次执行,得到时间如下:
使用plsql表的执行时间约在 0 . 04 秒。
而不使用plsql表的执行时间约在 8 . 33 秒。



create or replace procedure test_plsql_cursor
is


cursor cur_data_1 is
select tname,tabtype from tab;
cursor cur_data_2 is
select tname,tabtype from tab;
cursor cur_data_3 is
select tname,tabtype from tab;

---define record
type rectype_nametype is record (name varchar2(30),type varchar2(10));
---define plsql tab using record
type tab_nametype is table of rectype_nametype index by binary_integer;

---define plsql tab using cursor
type tab_type_1 is table of cur_data_1%rowtype index by binary_integer;
l_tab_1 cur_data_1%rowtype;

tab_1 tab_nametype;
tab_2 tab_type_1;
tab_3 tab_type_1;

l_tab_1_len int;
l_tab_2_len int;
l_tab_3_len int;

l_t int := 0;

begin

----------------------------
l_tab_1_len := 0;
open cur_data_1;
loop
fetch cur_data_1 into l_tab_1;
exit when cur_data_1%notfound;

tab_1(l_tab_1_len).name := l_tab_1.tname;
tab_1(l_tab_1_len).type := l_tab_1.tabtype;

l_tab_1_len := l_tab_1_len + 1;

end loop;
close cur_data_1;
l_tab_1_len := l_tab_1_len - 1;

----------------------------
l_tab_2_len := 0;
for I in cur_data_2
loop
tab_2(l_tab_2_len) := I;
l_tab_2_len := l_tab_2_len + 1;
end loop;
l_tab_2_len := l_tab_2_len - 1;

----------------------------
l_tab_3_len := 0;
for I in cur_data_3
loop
tab_3(l_tab_3_len) := I;
l_tab_3_len := l_tab_3_len + 1;
end loop;
l_tab_3_len := l_tab_3_len - 1;





-- loop test

for X in 0 .. l_tab_3_len
loop
for Y in 0 .. l_tab_2_len
loop
for Z in 0 .. l_tab_1_len
loop

l_t := l_t + 1;

end loop;
end loop;
end loop;



dbms_output.put_line ('l_t='||to_char(l_t));



end test_plsql_cursor;
/












create or replace procedure test_plsql_cursor_2
is


cursor cur_data_1 is
select tname,tabtype from tab;
cursor cur_data_2 is
select tname,tabtype from tab;
cursor cur_data_3 is
select tname,tabtype from tab;


---define plsql tab using cursor
type tab_type_1 is table of cur_data_1%rowtype index by binary_integer;
l_tab_1 cur_data_1%rowtype;


l_t int := 0;

begin

----------------------------
l_t := 0;
open cur_data_3;
loop
fetch cur_data_3 into l_tab_1;
exit when cur_data_3%notfound;

open cur_data_2;
loop
fetch cur_data_2 into l_tab_1;
exit when cur_data_2%notfound;

open cur_data_1;
loop
fetch cur_data_1 into l_tab_1;
exit when cur_data_1%notfound;

l_t := l_t + 1;

end loop;
close cur_data_1;

end loop;
close cur_data_2;

end loop;
close cur_data_3;





dbms_output.put_line ('l_t='||to_char(l_t));



end test_plsql_cursor_2;
/




bigboar 发表于:2006.10.17 13:42 ::分类: ( Oracle ) ::阅读:(688次) :: 评论 (2) :: 引用 (0)

其实时间是一样的 [回复]

差别在于后者每次都在循环内部打开关闭游标,如果将3个游标均移至循环外打开关闭,则时间基本一样
create or replace procedure test_plsql_cursor_2
is

cursor cur_data_1 is
select tname,tabtype from tab;
cursor cur_data_2 is
select tname,tabtype from tab;
cursor cur_data_3 is
select tname,tabtype from tab;

---define plsql tab using cursor
type tab_type_1 is table of cur_data_1%rowtype index by binary_integer;
l_tab_1 cur_data_1%rowtype;

l_t int := 0;

begin

----------------------------
l_t := 0;
open cur_data_3;
open cur_data_2;
open cur_data_1;

loop
fetch cur_data_3 into l_tab_1;
exit when cur_data_3%notfound;

loop
fetch cur_data_2 into l_tab_1;
exit when cur_data_2%notfound;

loop
fetch cur_data_1 into l_tab_1;
exit when cur_data_1%notfound;

l_t := l_t + 1;

end loop;
end loop;
end loop;

close cur_data_1;
close cur_data_2;
close cur_data_3;

dbms_output.put_line ('l_t='||to_char(l_t));

end test_plsql_cursor_2;

lift 评论于:2007.05.15 09:16

这只是一个用空间换时间的方式 [回复]

这只是一个用空间换时间的方式,在实际应用中还是需要根据具体情况而定的。
呵呵

nio 评论于:2007.04.12 10:03

发表评论

标题

在此添加评论

称呼

邮箱地址(可选)

个人主页(可选)


authimage