楼主: fromeast

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

[复制链接]
论坛徽章:
0
91#
发表于 2008-9-18 18:36 | 只看该作者
学习了,顶一个!

使用道具 举报

回复
论坛徽章:
57
秀才
日期:2017-08-18 11:06:452012新春纪念徽章
日期:2012-01-04 11:50:44ITPUB十周年纪念徽章
日期:2011-11-01 16:21:152011新春纪念徽章
日期:2011-02-18 11:43:33ITPUB9周年纪念徽章
日期:2010-10-08 09:28:532010新春纪念徽章
日期:2010-03-01 11:06:132010年世界杯参赛球队:朝鲜
日期:2010-02-22 16:02:522010年世界杯参赛球队:荷兰
日期:2010-02-22 12:53:212010年世界杯参赛球队:瑞士
日期:2010-01-21 17:04:522010年世界杯参赛球队:法国
日期:2010-01-21 12:44:59
92#
发表于 2008-9-18 18:40 | 只看该作者

re

原帖由 zhp6489 于 2008-9-11 11:36 发表
declare
maxrows number default 1000;
maxblocks number default 8;
v_partition_name varchar2(30);
v_relative_fno   number;
v_block_id       number;
v_blocks         number;
v_endblocks      number;
v_object_id      number;
rowid_table dbms_sql.Urowid_Table;
currcount_table dbms_sql.number_Table;
v_rowid         urowid;
v_rowid2        urowid;
cursor cur_extents is
       select PARTITION_NAME, RELATIVE_FNO, block_id, blocks
       from dba_extents a
       where a.owner = 'OWNER' and a.segment_name = 'T1'
       ORDER BY a.EXTENT_ID;
begin
  open cur_extents;
  LOOP
    EXIT WHEN cur_extents%NOTFOUND;
    FETCH cur_extents into v_partition_name, v_relative_fno, v_block_id, v_blocks;
    v_endblocks := 0;
    IF v_partition_name iS NULL THEN
       SELECT OBJECT_ID INTO v_object_id FROM dba_objects where owner = 'OWNER' AND OBJECT_NAME = 'T1'
              AND OBJECT_TYPE = 'TABLE';
    ELSE
       SELECT OBJECT_ID INTO v_object_id FROMdba_objects where owner = 'OWNER' AND OBJECT_NAME = 'T1'
              ANDSUBOBJECT_NAME = v_partition_name AND OBJECT_TYPE = 'TABLE PARTITION';
    END IF;
   
    while v_endblocks < v_blocks loop
         v_rowid := dbms_rowid.rowid_create(1,v_object_id, v_relative_fno, v_block_id + v_endblocks, 0);
          v_endblocks := v_endblocks + maxblocks;
          if v_endblocks > v_blocks THEN
            v_rowid2 :=dbms_rowid.rowid_create(1, v_object_id, v_relative_fno, v_block_id +v_blocks - 1, 1000);
          else
            v_rowid2 :=dbms_rowid.rowid_create(1, v_object_id, v_relative_fno, v_block_id +maxblocks - 1, 1000);
          end if;              

   
          select /*+ ROWID(T1) */T1.ROWID, T2.curr_count
          bulk collect into rowid_table, currcount_table
          FROM OWNER.T1 T1, OWNER.T2 T2
          WHERE T1.ID2 = T2.ID2 and T1.rowid between v_rowid AND v_rowid2;

          forall i in 1 .. rowid_table.count
                 update OWNER.T1 set curr_count=currcount_table(i)
                 where rowid= rowid_table(i);
           commit;
    end loop;
  end loop;
  close cur_extents;
end;

其中查询语句中的提示可以根据具体情况进行调整


此方法看起來似乎解決了一些問題。但是實際測試5分鐘才更新7800條。速度慢的超想象。

使用道具 举报

回复
论坛徽章:
57
秀才
日期:2017-08-18 11:06:452012新春纪念徽章
日期:2012-01-04 11:50:44ITPUB十周年纪念徽章
日期:2011-11-01 16:21:152011新春纪念徽章
日期:2011-02-18 11:43:33ITPUB9周年纪念徽章
日期:2010-10-08 09:28:532010新春纪念徽章
日期:2010-03-01 11:06:132010年世界杯参赛球队:朝鲜
日期:2010-02-22 16:02:522010年世界杯参赛球队:荷兰
日期:2010-02-22 12:53:212010年世界杯参赛球队:瑞士
日期:2010-01-21 17:04:522010年世界杯参赛球队:法国
日期:2010-01-21 12:44:59
93#
发表于 2008-9-18 18:53 | 只看该作者

RE

測試存在一些誤會。建立數據表的時候沒有制定PCT_FREE,默認的10導致行鏈接,速度很慢。
調整PCT FREE 30 后,測試10萬筆數據更新的耗費時間為10秒。照此速度5億數據大概需要13.8小時。當然,我的測試幾是PC.

使用道具 举报

回复
论坛徽章:
47
马上加薪
日期:2014-02-19 11:55:142011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:152011新春纪念徽章
日期:2011-01-25 15:41:502011新春纪念徽章
日期:2011-01-25 15:41:012010新春纪念徽章
日期:2010-03-01 11:20:512010年世界杯参赛球队:日本
日期:2010-02-26 11:04:222010新春纪念徽章
日期:2010-01-04 08:33:08祖国60周年纪念徽章
日期:2009-10-09 08:28:00生肖徽章2007版:牛
日期:2009-09-10 11:14:59
94#
发表于 2008-9-19 10:01 | 只看该作者
用sql
update set a.b=b.b where exists
代替plsql

使用道具 举报

回复
论坛徽章:
0
95#
发表于 2008-9-19 11:56 | 只看该作者
学习了,顶一个

使用道具 举报

回复
论坛徽章:
1
2009新春纪念徽章
日期:2009-01-04 14:52:28
96#
发表于 2008-9-19 12:50 | 只看该作者
原帖由 fromeast 于 2008-9-18 17:12 发表


回yaocf:没错,1000 rows/commit是因为怕影响前台。1万条一次commit,可能会锁记录长达1秒,影响比较大。



  楼主,确实有个问题,以前碰到过,就是你一边用SELECT选资料,一边又COMMIT资料,并且你这个运行这么长时间,很容易出现快照太久的

  在实际工作中,如果我看到程序员这么写的话,我会把程序打回去从新改的

  这个你应该考虑一下

使用道具 举报

回复
论坛徽章:
131
2006年度最佳技术回答
日期:2007-01-24 12:58:48福特
日期:2013-10-24 13:57:422014年新春福章
日期: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:142013年新春福章
日期:2013-02-25 14:51:24
97#
发表于 2008-9-19 13:01 | 只看该作者
ROWID的,请看这个
http://www.itpub.net/redirect.ph ... 86&ptid=1052077

原帖由 Marshaljlc 于 2008-9-15 19:39 发表
rowid也好,keep也罢,还有老和尚的方法,都没说明透彻。加精华值得商榷。

使用道具 举报

回复
论坛徽章:
66
现任管理团队成员
日期:2011-05-07 01:45:08版主9段
日期:2013-04-21 02:21:02ITPUB年度最佳版主
日期:2014-02-19 10:05:27ITPUB年度最佳版主
日期:2013-01-30 17:30:25ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05优秀写手
日期:2013-12-18 09:29:15元宝章
日期:2015-02-10 19:57:54金牌徽章
日期:2015-02-10 19:59:42银牌徽章
日期:2015-02-10 19:59:42铜牌徽章
日期:2015-02-10 19:59:41
98#
发表于 2008-9-19 13:02 | 只看该作者
用rowid快速更新确实提供了一个很好的思路

为什么不用forall呢?

我喜欢用forall来代替for  提高效率

使用道具 举报

回复
论坛徽章:
3
奥运会纪念徽章:铁人三项
日期:2008-08-14 11:45:20生肖徽章2007版:马
日期:2009-03-20 11:26:202010新春纪念徽章
日期:2010-03-01 11:19:07
99#
发表于 2008-9-19 13:37 | 只看该作者
这个贴看下来受益匪浅啊!

使用道具 举报

回复
论坛徽章:
0
100#
发表于 2008-9-19 14:16 | 只看该作者
经典,没有想到的说

使用道具 举报

回复

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

本版积分规则 发表回复

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