View Code
1 比如现在对一个表增加一个流水字段,非空,唯一。
2 该表数据量为3000000.
3 假设表名为test。
4
5 1.使用cursor。
6 declare
7 cursor c_test is select rowid from test;
8 v_test c_test %rowtype;
9 begin
10 open c_test;
11 loop
12 fetch c_test into v_test;
13 exit when c_test %notfound;
14 update test set sn = test_seq.nextval;
15 end loop;
16 close c_test;
17 end;
18
19 2.使用between ... and。
20 declare
21 -- 总的记录数
22 v_total number( 14, 0) : = 0;
23 -- 当前记录index
24 v_curr number( 14, 0) : = 0;
25 -- 记录上一次更新的位置
26 v_pri number( 14, 0) : = 0;
27 begin
28 -- 查出总共的记录数。
29 select count( *) from test into v_total;
30 for i in 1..v_total loop
31 v_curr : = v_curr + 1;
32 if v_curr mod 100000 = 0 then
33 update test set sn = test_seq.nextval where rownum between v_pri and v_curr;
34 end if;
35 -- 下一次更新开始的位置就是本次更新结束的位置
36 v_pri : = v_curr;
37 end loop;
38
39 -- 需要处理最后一部分数据,因为是100000次一提交,可能最后一部分不足100000,需要单独处理。
40 update test set sn = test_seq.nextval where rownum between v_pri and v_total;
41 end;
42
43 3.每一次更新都会查目前没有更改的记录数。
44 declare
45 -- 目前表中没有更改的记录数
46 v_not_updated_count number( 14, 0) : = 0;
47 begin
48 loop
49 select count( *) into v_not_updated_count from test where sn is null;
50 update test set sn = test_seq.nextval where rownum <= 100000 and sn is null;
51 exit when v_not_updated = 0;
52 end loop;
53 end;
54
55
56 效率比较:
57 1和2可能效率差不多。大概要1个半小时。
58 3需要10分钟左右。
2 该表数据量为3000000.
3 假设表名为test。
4
5 1.使用cursor。
6 declare
7 cursor c_test is select rowid from test;
8 v_test c_test %rowtype;
9 begin
10 open c_test;
11 loop
12 fetch c_test into v_test;
13 exit when c_test %notfound;
14 update test set sn = test_seq.nextval;
15 end loop;
16 close c_test;
17 end;
18
19 2.使用between ... and。
20 declare
21 -- 总的记录数
22 v_total number( 14, 0) : = 0;
23 -- 当前记录index
24 v_curr number( 14, 0) : = 0;
25 -- 记录上一次更新的位置
26 v_pri number( 14, 0) : = 0;
27 begin
28 -- 查出总共的记录数。
29 select count( *) from test into v_total;
30 for i in 1..v_total loop
31 v_curr : = v_curr + 1;
32 if v_curr mod 100000 = 0 then
33 update test set sn = test_seq.nextval where rownum between v_pri and v_curr;
34 end if;
35 -- 下一次更新开始的位置就是本次更新结束的位置
36 v_pri : = v_curr;
37 end loop;
38
39 -- 需要处理最后一部分数据,因为是100000次一提交,可能最后一部分不足100000,需要单独处理。
40 update test set sn = test_seq.nextval where rownum between v_pri and v_total;
41 end;
42
43 3.每一次更新都会查目前没有更改的记录数。
44 declare
45 -- 目前表中没有更改的记录数
46 v_not_updated_count number( 14, 0) : = 0;
47 begin
48 loop
49 select count( *) into v_not_updated_count from test where sn is null;
50 update test set sn = test_seq.nextval where rownum <= 100000 and sn is null;
51 exit when v_not_updated = 0;
52 end loop;
53 end;
54
55
56 效率比较:
57 1和2可能效率差不多。大概要1个半小时。
58 3需要10分钟左右。