表结构如下
create table mytable
(
RE_ID NUMBER(4) not null, --地区ID
TI_ID NUMBER(6) not null, --日期ID
CH_ID VARCHAR2(1) not null, --业务ID
TYPE VARCHAR2(1) not null, --业务类型
USERID VARCHAR2(1) not null, --业务品牌
ACTYPE_ID NUMBER(3) not null, --错误ID
OPER_COUNTS NUMBER(16) --次数
)
我现在要实现的就是想把这个表的OPER_COUNTS(次数)计算出来并更新,其更新规则是要求计算出,在同一地区ID,同一日期ID,同一业务ID,同一业务类型,同一业务品牌,同一错误ID,的次数,也就是说这个次数OPER_COUNTS字段,合计的数次要同时满足以上六个条件共存才行.
我做了两个方法,能实现,就是速度慢,因为我这个表至少有1000万条记录:
我的方法一:用游标实现
CURSOR oper_counts_cur IS
SELECT RE_ID,TI_ID,CH_ID,TYPE,USERID,ACTYPE_ID
FROM mytable;
OPEN oper_counts_cur;
LOOP
FETCH oper_counts_cur INTO n_RE_ID,n_TI_ID,v_CH_ID,v_TYPE,v_USERID,n_ACTYPE_ID;
EXIT WHEN oper_counts_cur%NOTFOUND;
UPDATE mytable SET oper_counts=(
SELECT COUNT(*) FROM mytable
WHERE userid=v_USERID
AND ch_id=v_CH_ID
AND type=v_TYPE
AND ti_id=n_TI_ID
AND re_id=n_RE_ID
AND actype_id=n_ACTYPE_ID);
END LOOP;
CLOSE oper_counts_cur;
COMMIT;方法二:直接用update语句修改
UPDATE mytable b SET b.oper_counts=(
SELECT COUNT(*) FROM mytable a
WHERE a.userid=b.userid
AND a.ch_id=b.ch_id
AND a.type=b.type
AND a.ti_id=b.ti_id
AND a.re_id=b.re_id
AND a.actype_id=b.actype_id);
COMMIT;
以上两个方法,跑起来都特别慢,几个小时也跑不完呀,哪位高手帮帮我,看看有没有什么好的解决方案呀,小弟,在线等!!!
create table mytable
(
RE_ID NUMBER(4) not null, --地区ID
TI_ID NUMBER(6) not null, --日期ID
CH_ID VARCHAR2(1) not null, --业务ID
TYPE VARCHAR2(1) not null, --业务类型
USERID VARCHAR2(1) not null, --业务品牌
ACTYPE_ID NUMBER(3) not null, --错误ID
OPER_COUNTS NUMBER(16) --次数
)
我现在要实现的就是想把这个表的OPER_COUNTS(次数)计算出来并更新,其更新规则是要求计算出,在同一地区ID,同一日期ID,同一业务ID,同一业务类型,同一业务品牌,同一错误ID,的次数,也就是说这个次数OPER_COUNTS字段,合计的数次要同时满足以上六个条件共存才行.
我做了两个方法,能实现,就是速度慢,因为我这个表至少有1000万条记录:
我的方法一:用游标实现
CURSOR oper_counts_cur IS
SELECT RE_ID,TI_ID,CH_ID,TYPE,USERID,ACTYPE_ID
FROM mytable;
OPEN oper_counts_cur;
LOOP
FETCH oper_counts_cur INTO n_RE_ID,n_TI_ID,v_CH_ID,v_TYPE,v_USERID,n_ACTYPE_ID;
EXIT WHEN oper_counts_cur%NOTFOUND;
UPDATE mytable SET oper_counts=(
SELECT COUNT(*) FROM mytable
WHERE userid=v_USERID
AND ch_id=v_CH_ID
AND type=v_TYPE
AND ti_id=n_TI_ID
AND re_id=n_RE_ID
AND actype_id=n_ACTYPE_ID);
END LOOP;
CLOSE oper_counts_cur;
COMMIT;方法二:直接用update语句修改
UPDATE mytable b SET b.oper_counts=(
SELECT COUNT(*) FROM mytable a
WHERE a.userid=b.userid
AND a.ch_id=b.ch_id
AND a.type=b.type
AND a.ti_id=b.ti_id
AND a.re_id=b.re_id
AND a.actype_id=b.actype_id);
COMMIT;
以上两个方法,跑起来都特别慢,几个小时也跑不完呀,哪位高手帮帮我,看看有没有什么好的解决方案呀,小弟,在线等!!!
解决方案 »
- 悬赏100分,急急急,救命,爬地求救.搞不好,会被开.
- oracle数据导入导出问题
- 存储过程参数输入错误
- 100分求一巨难页而且很实用的SQL语句!!
- 怎样在SQL SERVER的存储过程中调用ORACLE的过程,急!!
- 关于关键字的问题
- 新手提问:客户端如何知道服务器数据库名?
- Oracle的存储过程里可以这样写吗:select case when (cost>2) then '大' else '小' end from table ?
- 关于Oracle的双网卡访问的问题,急!
- 在线等 oracle配置问题
- 如何把文本数据导到oracle表中
- Oracle奇怪问题:Sql语句在客户端通过Plsql执行没有反映,但在服务器上却可以执行.
然后对各个分区表进行处理
避免大批量数据操作
那还是乖乖的按照你的where子句的条件,建立索引吧
declare
v_rowcount number;
begin
loop
update T_CARCASE_CAR
set CREATED_BY = user,CREATED_DATE=sysdate,UPDATED_BY=user,UPDATED_DATE=sysdate
where CREATED_BY=null or CREATED_DATE=null or UPDATED_BY=null or UPDATED_DATE=null
and rownum<100001;
v_rowcount:=sql%rowcount;
commit;
exit when v_rowcount<100000; -- 当sql返回的记录数<100000时,说明已经是最后一次循环了,符合exit出循环的条件了
end loop;
end;
/
给你个示例,每10w条记录update一次
v_rowcount number;
begin
loop
UPDATE mytable b SET b.oper_counts=(
SELECT COUNT(*) FROM mytable a
WHERE a.userid=b.userid
AND a.ch_id=b.ch_id
AND a.type=b.type
AND a.ti_id=b.ti_id
AND a.re_id=b.re_id
AND a.actype_id=b.actype_id);
v_rowcount:=sql%rowcount;
commit;
exit when v_rowcount<100000; -- 当sql返回的记录数<100000时,说明已经是最后一次循环了,符合exit出循环的条件了
end loop;
end;
/
不管使用哪种方式,都不会在短时间内完成。如果一次性计算全部建议将任务分开执行,比如可以按地区或者是地区
将数据分开,每个程序完成一个地区的计算,这样就可以同时运行多个程序,多个地区同时计算。写一个带有一个 输入参数的过程,参数为地区编号,这样可以将不同地区的计算分开,相当于并行了。如果有10个地区,就可以当作10个job来运行,速度自然会快。
如果是实时更新,就简单了