表A 记录3600W行 表大小大概2.4G
主要字段
serv_id number
serv_type_id number
其中serv_id是主键,serv_type_id为空,需要update表B 记录4200W行 表大小大概7.3G
主要字段
serv_id number
serv_seq_nbr number
serv_type_id
其中serv_id和serv_seq_nbr是联合主键.
同一个serv_id对应多个serv_seq_nbr,serv_seq_nbr分别为0、1、2、……N,
现在需要做的就是,UPDATE A 表 的serv_type_id的字段,根据serv_id在B表中找到对应的serv_id记录并以serv_seq_nbr为最大值的那条所对应的serv_type_id.
现在更新超慢,用函数+批量绑定+原子处理都不能达到理想效果,估计更新时间30个小时。
注:写了一个根据serv_id取serv_type_id的小函数,游标批量绑定以10000条一批
有没有什么好办法?
主要字段
serv_id number
serv_type_id number
其中serv_id是主键,serv_type_id为空,需要update表B 记录4200W行 表大小大概7.3G
主要字段
serv_id number
serv_seq_nbr number
serv_type_id
其中serv_id和serv_seq_nbr是联合主键.
同一个serv_id对应多个serv_seq_nbr,serv_seq_nbr分别为0、1、2、……N,
现在需要做的就是,UPDATE A 表 的serv_type_id的字段,根据serv_id在B表中找到对应的serv_id记录并以serv_seq_nbr为最大值的那条所对应的serv_type_id.
现在更新超慢,用函数+批量绑定+原子处理都不能达到理想效果,估计更新时间30个小时。
注:写了一个根据serv_id取serv_type_id的小函数,游标批量绑定以10000条一批
有没有什么好办法?
解决方案 »
- create table问题:
- drop表的索引会导致过程失效么?
- 关于oracle 8i 排序后区前几名的问题?
- oracle的数据备份的大小是不是和它的tablespace的大小有关?
- LINUX下怎么装ORACLE?/用的盘是不是和WINDOWS的盘不一样,要买LINUX环境的吗???
- about join
- oracle数据库导错误解析,在线等待!!!急!!!呼唤高手指教!!!
- 在oracle中当输入的字超过2000字以上插入到数据库中,用什么方法实现的?
- 请求高人指点!帮忙解决sql语句问题
- 在存储过程中用传递参数形成sql语句
- 【如何程序打包的时候创建“用户,表,并添加一些数据”】
- Pro*C中预编译时,选择“编辑”->“选项”时弹出一个内容为“ANSI”的MSG框......
UPDATE A
SET serv_type_id=GET_SERV_TYPE_ID(serv_id)
WHERE serv_type_id IS NULL
AND serv_id BETWEEN (Batch_Counter-1)*10000 AND Batch_Counter*10000
END LOOP;如果你函数 GET_SERV_TYPE_ID 效率可以的话,那么这种方式应该还行,因为用到了主键索引的局部扫描。你可以先把循环的上下界都改成1,也就是说只执行一次循环,更新10000条,看看需要多少时间
TYPE t_serv_id IS TABLE OF testb.serv_id%TYPE;
TYPE t_serv_seq_nbr IS TABLE OF testb.serv_seq_nbr%TYPE;
-- 定义保存源数据的数组
arr_serv_id t_serv_id;
arr_serv_seq_nbr t_serv_seq_nbr;
-- 更新的数据源,下面用游标批量读取
CURSOR c IS
SELECT serv_id, MAX(serv_seq_nbr) serv_seq_nbr FROM testb GROUP BY serv_id;
BEGIN
OPEN c;
LOOP
-- 批量更新,一次更新1000条数据,防止数据量过大内存溢出
fetch c bulk collect into arr_serv_id, arr_serv_seq_nbr LIMIT 100;
-- 这里用forall比for效率高很多
FORALL i IN 1 .. arr_serv_id.COUNT
UPDATE testa SET serv_type_id = arr_serv_seq_nbr(i) WHERE serv_id = arr_serv_id(i);
-- 循环退出,注意不要放在循环前面
COMMIT;
exit when c%NOTFOUND;
END LOOP;
--COMMIT;END bulk_update;