楼主: fromeast

利用rowid快速在线更新海量数据

[复制链接]
论坛徽章:
19
ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:06:13BLOG每日发帖之星
日期:2010-03-28 01:01:02ITPUB9周年纪念徽章
日期:2010-10-08 09:31:222012新春纪念徽章
日期:2012-01-04 11:51:22
41#
发表于 2008-9-9 08:22 | 只看该作者
good idea!

使用道具 举报

回复
论坛徽章:
27
设计板块每日发贴之星
日期:2007-08-24 01:05:17奥运会纪念徽章:拳击
日期:2012-06-25 14:17:112012新春纪念徽章
日期:2012-01-04 11:49:54生肖徽章2007版:龙
日期:2009-04-07 18:18:35生肖徽章2007版:鸡
日期:2008-10-14 14:14:30生肖徽章2007版:龙
日期:2008-10-08 21:22:20铁扇公主
日期:2008-09-28 11:20:58授权会员
日期:2008-09-05 13:30:44ITPUB元老
日期:2008-09-05 13:30:31奥运会纪念徽章:摔跤
日期:2008-07-26 08:05:05
42#
发表于 2008-9-9 08:46 | 只看该作者
很不错的想法,学习了

使用道具 举报

回复
论坛徽章:
19
授权会员
日期:2007-08-25 20:02:41会员2007贡献徽章
日期:2007-09-26 18:42:10BLOG每日发帖之星
日期:2008-11-13 01:01:05
43#
发表于 2008-9-9 08:48 | 只看该作者
很好,利用rowid和bulk collect.

使用道具 举报

回复
招聘 : 软件工程师
论坛徽章:
51
ITPUB元老
日期:2007-09-25 14:45:26现代
日期:2014-02-10 13:35:242014年新春福章
日期:2014-02-18 16:41:11马上有车
日期:2014-02-18 16:41:11马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上加薪
日期:2014-02-19 11:55:14马上有车
日期:2014-08-25 08:54:25
44#
发表于 2008-9-9 10:12 | 只看该作者
原帖由 TO_TO_RO 于 2008-9-8 08:52 发表
这么大的表用游标遍历不太合适

这句说的经典

使用道具 举报

回复
论坛徽章:
10
ITPUB元老
日期:2005-02-28 12:57:002010广州亚运会纪念徽章:保龄球
日期:2011-01-30 11:57:03祖国60周年纪念徽章
日期:2009-10-09 08:28:00参与2009年中国云计算大会纪念
日期:2009-06-05 10:02:28ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452009新春纪念徽章
日期:2009-01-04 14:52:28生肖徽章2007版:鼠
日期:2008-01-02 17:35:53会员2006贡献徽章
日期:2006-04-17 13:46:34授权会员
日期:2005-10-30 17:05:33ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41
45#
 楼主| 发表于 2008-9-9 12:50 | 只看该作者
原帖由 goodhawk 于 2008-9-8 23:29 发表
应该跟如下的写法差不多, 同时建议不要 1000 commit 一次, 可以考虑 10000 或者 30000 左右来一次,
太频繁也是浪费时间.

CURSOR c1 IS
    SELECT object_name,object_id,status
    FROM up
    ORDER BY object_name
    FOR UPDATE OF status;

BEGIN

FOR acct IN c1 LOOP   -- process each row one at a time   
  IF acct.status='INVALID' THEN
       UPDATE up SET status='TEST'
       WHERE current of c1;
  END IF;
END LOOP;

COMMIT;
END;


T1是在线表,用1000是为了减少对T1的锁定时间,按10000 rows/s的算,1秒会COMMIT 10次,我觉得不会造成太大的问题。但是用10000或30000,就会锁记录最长达到1秒或3秒,可能会影响在线业务。

[ 本帖最后由 fromeast 于 2008-9-9 13:02 编辑 ]

使用道具 举报

回复
论坛徽章:
10
ITPUB元老
日期:2005-02-28 12:57:002010广州亚运会纪念徽章:保龄球
日期:2011-01-30 11:57:03祖国60周年纪念徽章
日期:2009-10-09 08:28:00参与2009年中国云计算大会纪念
日期:2009-06-05 10:02:28ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452009新春纪念徽章
日期:2009-01-04 14:52:28生肖徽章2007版:鼠
日期:2008-01-02 17:35:53会员2006贡献徽章
日期:2006-04-17 13:46:34授权会员
日期:2005-10-30 17:05:33ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41
46#
 楼主| 发表于 2008-9-9 13:00 | 只看该作者
原帖由 wgz7747 于 2008-9-9 10:12 发表

这句说的经典


确实发现了问题,在运行了8个小时后,报错退出了。错误码是ORA-600 [4454]。根据metalink上的资料,应该是9.2存在的BUG,原因是长时间的BATCH JOB造成savepoint号绕回,引发了ORA-600。现在的解决方法是找到报错之前更新的行数n,然后修改脚本,加个限制,更新到n-1000万行,就退出,再重启脚本。这样做的缺点是每次重启,都要耗费额外的时间在打开CURSOR上,约70分钟。

[ 本帖最后由 fromeast 于 2008-9-9 13:05 编辑 ]

使用道具 举报

回复
论坛徽章:
125
ITPUB社区12周年站庆徽章
日期:2013-08-13 16:52:38ITPUB十周年纪念徽章
日期:2011-11-01 16:21:15NBA季后赛纪念徽章
日期:2011-06-13 11:34:51欧洲冠军杯纪念徽章
日期:2011-05-30 17:39:52NBA常规赛纪念章
日期:2011-04-15 13:34:112011新春纪念徽章
日期:2011-02-18 11:43:342011新春纪念徽章
日期:2011-01-16 22:27:502011新春纪念徽章
日期:2011-01-04 10:24:022010广州亚运会纪念徽章:橄榄球
日期:2010-12-22 23:50:552010广州亚运会纪念徽章:乒乓球
日期:2010-11-03 12:50:58
47#
发表于 2008-9-9 14:27 | 只看该作者
不错  支持原创~

使用道具 举报

回复
论坛徽章:
314
行业板块每日发贴之星
日期:2012-07-12 18:47:29双黄蛋
日期:2011-08-12 17:31:04咸鸭蛋
日期:2011-08-18 15:13:51迷宫蛋
日期:2011-08-18 16:58:25紫蛋头
日期:2011-08-31 10:57:28ITPUB十周年纪念徽章
日期:2011-09-27 16:30:47蜘蛛蛋
日期:2011-10-20 15:51:25迷宫蛋
日期:2011-10-29 11:12:59ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41鲜花蛋
日期:2011-11-09 20:33:30
48#
发表于 2008-9-9 20:37 | 只看该作者
原帖由 rollingpig 于 2008-9-8 16:08 发表
加一个for all, 效果会更好
declare
maxrows number default 1000;
row_id_table dbms_sql.Urowid_Table;
currcount_table dbms_sql.number_Table;
  cursor cur_t2 is
    select /*+ use_hash(T1,T2) parallel(T1,16) parallel_index(IX_T1_id2,16) */
       T2.id2, T2.curr_count, T1.rowid row_id
    from T1, T2
    where T1.id2=T2.id2
    order by T1.rowid;
  v_counter number;
begin
  v_counter := 0;
open cur_t2;
LOOP
EXIT WHEN cur_t2%NOTFOUND;
FETCH cur_t2 bulk collect into row_id_table,currcount_table limit maxrows;
forall i in 1 .. row_id_table.count
    update T1 set curr_count=currcount_table(i)
       where rowid= row_id_table(i);
      commit;
  end loop;
end;
/
参考:
http://space.itpub.net/1249/viewspace-64339


请滚珠区确认一下,你这里定义的
row_id_table dbms_sql.Urowid_Table;
currcount_table dbms_sql.number_Table;
是否合适?我看不明白,

我觉得,先定义游标,再用游标定义内存表比较合适?

使用道具 举报

回复
论坛徽章:
7
奥运会纪念徽章:皮划艇激流回旋
日期:2008-07-23 14:49:16生肖徽章2007版:兔
日期:2008-10-06 17:32:12奥运会纪念徽章:跳水
日期:2008-10-24 13:09:39生肖徽章2007版:兔
日期:2008-11-11 08:20:05生肖徽章2007版:龙
日期:2009-05-02 12:09:05生肖徽章2007版:狗
日期:2009-08-19 16:52:22祖国60周年纪念徽章
日期:2009-10-09 08:28:00
49#
发表于 2008-9-9 20:55 | 只看该作者
经典,突然觉得自己什么都不会。

使用道具 举报

回复
论坛徽章:
1
ITPUB十周年纪念徽章
日期:2011-11-01 16:21:15
50#
发表于 2008-9-9 23:33 | 只看该作者
excellent!

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表