mysql bulk collect_fetch bulk collect into 简单学习

/*

fetch bulk collect into 的使用格式是:fetchsome_cursorbulk collectintocol1, col2 limit xxx。

col1、col2 是声明的集合类型变量,xxx 为每次取数据块的大小(记录数),

相当于缓冲区的大小,可以不指定 limit xxx 大小

*/

-- 1.给一张表加数据,以便测试用

declareinumber(8) := 0;

begin

for i in 0..100000 loop

insert into t_user(id,username,password) values(seq_t_user.nextVal,'xiweiyuan'||i,'xiweiyuan'||i);

end loop;

end;

/

-- 或者这样--

begin

for i in 1..200000 loop

insert into t_user(id,username,password) select seq_t_user.nextVal,'hanchao','xiweiyuan' from dual;

end loop;

commit;

end;

/

--2.使用fetch bulk collect into 获取游标的数据

declare

-- 声明需要集合类型及变量,参照字段的type来声明类型。

typeid_typeistable of t_user.id%type;

v_idid_type;

type username_type is table of t_user.username%type;

v_username username_type;

type password_type is table of t_user.password%type;

v_password password_type;

cursor cur_t_user is select id,username,password from t_user whererownum<= 1000 ;--for update;

i number(8) := 0;

j number(8) := 0;

begin

open cur_t_user;

loop

i := i + 1; -- 记录外层循环多少次

fetchcur_t_userbulk collectintov_id,v_username,v_passwordlimit256;

--dbms_output.put_line('fetch OK → 缓冲区大小:' || v_id.count || ',外层循环次数 :' || i);

for j in1..v_id.countloop-- 遍历集合

-- dbms_output.put_line('fetch OK → 缓冲区大小:' || v_id.count || ',内层循环次数 :' || j);

insert into t_user_bak(id,u,p) values(v_id(j),v_username(j),v_password(j));

--null;

end loop;

exit when cur_t_user%notfound; --exit 不能紧跟着fetch后面了,不然最后不够256部分会被漏掉

end loop;

close cur_t_user;

end;

/

--3.使用%rowtype的例子

declare

-- 声明需要集合类型及变量,参照字段的type来声明类型。

type user_type is table oft_user%rowtype;

v_user user_type;

n number(5) := 0;

cursor cur_t_user is --用rownum来限制取出的记录的条数

select * from t_user where rownum <= 100;

begin

open cur_t_user;

loop

n := n + 1;

fetch cur_t_user bulk collect into v_user limit 10;

if v_user.count = 0 then

exit;

end if;

dbms_output.put_line('fetch OK → 缓冲区大小:' || v_user.count || ',begin :' || v_user.first || ',end :' || v_user.last || ',,循环的次数:' || n);

for i inv_user.first..v_user.lastloop --遍历集合

dbms_output.put_line('nei  缓冲区大小:' || v_user.count || ',begin :' || v_user.first || ',end :' || v_user.last || ',,循环的次数:' || n);

insert into t_user_bak(id,u,p) values(v_user(i).id,v_user(i).username,v_user(i).password);

end loop;

exit when cur_t_user%notfound;

end loop;

close cur_t_user;

end;

/

--4.使用%rowtype的例子,不用last

declare

-- 声明需要集合类型及变量,参照字段的type来声明类型。

type user_type is table oft_user%rowtype;

v_user user_type;

n number(5) := 0;

i number(5) := 0;

cursor cur_t_user is --用rownum来限制取出的记录的条数

select * from t_user where rownum <= 100000;

begin

open cur_t_user;

loop

n := n + 1;

fetch cur_t_user bulk collect into v_user limit 256;

-- dbms_output.put_line('fetch OK → 缓冲区大小:' || v_user.count || ',begin :' || v_user.first || ',end :' || v_user.last || ',,外层循环的次数:' || n);

for i in 1..v_user.count loop--遍历集合

-- dbms_output.put_line('nei  缓冲区大小:' || v_user.count || ',begin :' || v_user.first || ',end :' || v_user.last || ',,外层循环的次数:' || n  || ',内层循环次数:' || i);

insert into t_user_bak(id,u,p) values(v_user(i).id,v_user(i).username,v_user(i).password);

end loop;

exit when cur_t_user%notfound;

end loop;

close cur_t_user;

end;

/

--5.使用%rowtype的例子,例4加forall 此种方法与上面几种方法貌似就不是一个数量级的,很快

declare

-- 声明需要集合类型及变量,参照字段的type来声明类型。

type user_type is table of t_user%rowtype;

v_user user_type;

n number(5) := 0;

i number(5) := 0;

cursor cur_t_user is --用rownum来限制取出的记录的条数

select * from t_user where rownum <= 1000;

begin

open cur_t_user;

loop

n := n + 1;

fetch cur_t_user bulk collect into v_user limit 256;

dbms_output.put_line('fetch OK → 缓冲区大小:' || v_user.count || ',begin :' || v_user.first || ',end :' || v_user.last || ',,外层循环的次数:' || n);

forall i in 1..v_user.count--loop --遍历集合

insert into t_user_bak(id,u,p) values(v_user(i).id,v_user(i).username,v_user(i).password);

--end loop;

exit when cur_t_user%notfound;

end loop;

close cur_t_user;

end;

/

你可以根据你的实际来调整 limit 参数的大小,来达到你最优的性能。limit 参数会影响到 pga 的使用率。

参考地址如下:

有问题再讨论吧。晚安。亲

=====================================================================================

----批量提交

declare

-- 声明需要集合类型及变量,参照字段的type来声明类型。

type user_type is table of t_user%rowtype;

v_user user_type;

n number(5) := 0;

i number(5) := 0;

y number(10) := 0;

cursor cur_t_user is --用rownum来限制取出的记录的条数

select * from t_user where rownum <= 300002;

begin

open cur_t_user;

loop

n := n + 1;

fetch cur_t_user bulk collect into v_user limit 256;

-- dbms_output.put_line('fetch OK → 缓冲区大小:' || v_user.count || ',begin :' || v_user.first || ',end :' || v_user.last || ',,外层循环的次数:' || n);

for i in 1..v_user.count loop --遍历集合

y := y + 1;

insert into t_user_bak(id,u,p) values(v_user(i).id,v_user(i).username,v_user(i).password);

-- 批量提交数据

if mod(y,5000) = 0 then

dbms_output.put_line('commit...');

commit;

end if;

end loop;

commit;

exit when cur_t_user%notfound;

end loop;

dbms_output.put_line(y);

close cur_t_user;

end;

/

--发现批量提交在速度方面没有明显提高啊!

----------------------------------------------------------------------------------------------------------------------

declare

-- 声明需要集合类型及变量,参照字段的type来声明类型。

type user_type is table of t_user%rowtype;

v_user user_type;

n number(5) := 0;

i number(5) := 0;

cursor cur_t_user is --用rownum来限制取出的记录的条数

select * from t_user where rownum <= 300002;

begin

open cur_t_user;

loop

n := n + 1;

fetch cur_t_user bulk collect into v_user limit 256;

-- dbms_output.put_line('fetch OK → 缓冲区大小:' || v_user.count || ',begin :' || v_user.first || ',end :' || v_user.last || ',,外层循环的次数:' || n);

forall i in 1..v_user.count --loop --遍历集合

insert into t_user_bak(id,u,p) values(v_user(i).id,v_user(i).username,v_user(i).password);

--end loop;

commit;

exit when cur_t_user%notfound;

end loop;

close cur_t_user;

end;

/

------------------------------------------------------------------------------------------------

批量插入时,这样的效率貌似也挺快,但是数据良超大时,需要注意了!

begin

insert into t_user_bak(id,u,p) select id,username,password from t_user;

commit;

end;

/

================================================================================

关于Forall的一些用法,我们必须要注意的一些东西,以下是参考文章:

累死了。不搞了。准备下班去。

================================================================================

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值