ROWID 切片

对于大表的update,delete,很容易引起undo不够的问题,特别是在一个session里面运行的时候,或者由于其他原因导致的回滚操作,这个就比较苦逼了,如果是分区表,可能影响稍微小一点,我们可以按照分区来进行更新,按照分区来进行delete。对于不是分区表的情况,就可以用rowid切片,然后开启多个进程并行处理,这样既能提升不少的速度,也能减少undo,防止死事物恢复太慢。

我这里有test_b表,表中有2793440条数据,我们简单的按照rowid切片对表进行处理

SQL> select count(*) from test_b;
COUNT(*)
--------
 2793440
 
select ‘where rowid between ‘‘‘ ||sys.dbms_rowid.rowid_create(1, d.oid, c.fid1, c.bid1, 0) ||‘‘‘ and ‘‘‘ ||sys.dbms_rowid.rowid_create(1, d.oid, c.fid2, c.bid2, 9999) || ‘‘‘‘ ||‘;‘
  from (select distinct b.rn,
                        first_value(a.fid) over(partition by b.rn order by a.fid, a.bid rows between unbounded preceding and unbounded following) fid1,
                        last_value(a.fid) over(partition by b.rn order by a.fid, a.bid rows between unbounded preceding and unbounded following) fid2,
                        first_value(decode(sign(range2 - range1),
                                           1,
                                           a.bid +
                                           ((b.rn - a.range1) * a.chunks1),
                                           a.bid)) over(partition by b.rn order by a.fid, a.bid rows between unbounded preceding and unbounded following) bid1,
                        last_value(decode(sign(range2 - range1),
                                          1,
                                          a.bid +
                                          ((b.rn - a.range1 + 1) * a.chunks1) - 1,
                                          (a.bid + a.blocks - 1))) over(partition by b.rn order by a.fid, a.bid rows between unbounded preceding and unbounded following) bid2
          from (select fid,
                       bid,
                       blocks,
                       chunks1,
 19                         trunc((sum2 - blocks + 1 - 0.1) / chunks1) range1,
                       trunc((sum2 - 0.1) / chunks1) range2
                  from (select /*+ rule */
                         relative_fno fid,
                         block_id bid,
                         blocks,
                         sum(blocks) over() sum1,
                         trunc((sum(blocks) over()) / &&rowid_ranges) chunks1,
                         sum(blocks) over(order by relative_fno, block_id) sum2
                          from dba_extents
                         where segment_name = upper(‘&&segment_name‘)
                           and owner = upper(‘&&owner‘))
                 where sum1 > &&rowid_ranges) a,
               (select rownum - 1 rn
                  from dual
                connect by level <= &&rowid_ranges) b
         where b.rn between a.range1 and a.range2) c,
       (select max(data_object_id) oid
          from dba_objects
         where object_name = upper(‘&&segment_name‘)
           and owner = upper(‘&&owner‘)
           and data_object_id is not null) d
Enter value for rowid_ranges: 15
old  26:     trunc((sum(blocks) over()) / &&rowid_ranges) chunks1,
new  26:     trunc((sum(blocks) over()) / 15) chunks1,
Enter value for segment_name: test_b
old  29:     where segment_name = upper(‘&&segment_name‘)
new  29:     where segment_name = upper(‘test_b‘)
Enter value for owner: scott
old  30:       and owner = upper(‘&&owner‘))
new  30:       and owner = upper(‘scott‘))
old  31:    where sum1 > &&rowid_ranges) a,
new  31:    where sum1 > 15) a,
old  34:   connect by level <= &&rowid_ranges) b
new  34:   connect by level <= 15) b
old  38:   where object_name = upper(‘&&segment_name‘)
new  38:   where object_name = upper(‘test_b‘)
old  39:     and owner = upper(‘&&owner‘)
new  39:     and owner = upper(‘scott‘)
‘WHEREROWIDBETWEEN‘‘‘||SYS.DBMS_ROWID.ROWID_CREATE(1,D.OID,C.FID1,------------------------------------------------------------------where rowid between ‘AAAqh3AAIAAAACIAAA‘ and ‘AAAqh3AAIAAABYpCcP‘;where rowid between ‘AAAqh3AAIAAABYqAAA‘ and ‘AAAqh3AAIAAACCpCcP‘;where rowid between ‘AAAqh3AAIAAACCqAAA‘ and ‘AAAqh3AAIAAACspCcP‘;where rowid between ‘AAAqh3AAIAAACsqAAA‘ and ‘AAAqh3AAIAAADOpCcP‘;where rowid between ‘AAAqh3AAIAAADOqAAA‘ and ‘AAAqh3AAIAAAD+pCcP‘;where rowid between ‘AAAqh3AAIAAAD+qAAA‘ and ‘AAAqh3AAIAAAEepCcP‘;where rowid between ‘AAAqh3AAIAAAEeqAAA‘ and ‘AAAqh3AAIAAAFOpCcP‘;where rowid between ‘AAAqh3AAIAAAFOqAAA‘ and ‘AAAqh3AAIAAAF+pCcP‘;where rowid between ‘AAAqh3AAIAAAF+qAAA‘ and ‘AAAqh3AAIAAAGepCcP‘;where rowid between ‘AAAqh3AAIAAAGeqAAA‘ and ‘AAAqh3AAIAAAHOpCcP‘;where rowid between ‘AAAqh3AAIAAAHOqAAA‘ and ‘AAAqh3AAIAAAH+pCcP‘;where rowid between ‘AAAqh3AAIAAAH+qAAA‘ and ‘AAAqh3AAIAAAIepCcP‘;where rowid between ‘AAAqh3AAIAAAIeqAAA‘ and ‘AAAqh3AAIAAAJOpCcP‘;where rowid between ‘AAAqh3AAIAAAJOqAAA‘ and ‘AAAqh3AAIAAAJ+pCcP‘;where rowid between ‘AAAqh3AAIAAAJ+qAAA‘ and ‘AAAqh3AAIAAAKepCcP‘;
15 rows selected.
Elapsed: 00:05:33.55

上面的例子,把test_b表分成15个rowid片,运行rowid切片sql的时候,需要传入3个参数,第一个是切片数量,第二个是切片对象,第三个是切片对象所属的对象,也就是owner,sql最终输出的结果可以看到,按照rowid对test_b表进行了切片,在update和delete的时候,分成15个session,加上并行处理,速度比直接update和delete快很多。

直接update操作:

SQL> update test_b set object_id=100;
2793440 rows updated.
Elapsed: 00:24:19.65

花了24分钟 ,占用了大量的UNDO表空间

之后便是相同的时间的ROLLBACK,

可以查询回滚的速度:

SQL> select KTUXESIZ from x$ktuxe where KTUXESTA<>‘INACTIVE‘;
KTUXESIZ--------   85462
SQL> rollback;
Rollback complete.
Elapsed: 00:50:36.58  
SQL> update test_b set object_id=100 where rowid between ‘AAAqh3AAIAAAACIAAA‘ and ‘AAAqh3AAIAAABYpCcP‘;
375065 rows updated.
Elapsed: 00:01:47.92SQL> update /* +parallel(test_b 4) */ test_b set object_id=100 where rowid between ‘AAAqh3AAIAAABYqAAA‘ and ‘AAAqh3AAIAAACCpCcP‘;
185986 rows updated.
Elapsed: 00:00:57.22
时间: 2024-11-22 20:35:35

ROWID 切片的相关文章

GoLang笔记-数组和切片,本质是就是长度不可变的可变的区别

数组 Arrays 数组是内置(build-in)类型,是一组同类型数据的集合,它是值类型,通过从0开始的下标索引访问元素值.在初始化后长度是固定的,无法修改其长度.当作为方法的入参传入时将复制一份数组而不是引用同一指针.数组的长度也是其类型的一部分,通过内置函数len(array)获取其长度. 初始化 数组的初始化有多种形式,查看示例代码 , 在线运行示例代码 [5] int {1,2,3,4,5} 长度为5的数组,其元素值依次为:1,2,3,4,5 [5] int {1,2} 长度为5的数组

Go语言切片初识

Go切片(Slice)是Go数组的一个抽象. 由于Go数组允许定义类型的变量,可以容纳相同数据类型的几个数据项,但它不提供任何内置的方法来动态增加其大小或获取自己的子数组.切片就没有这样的限制. 它提供了数组所需的许多实用功能,并广泛用于Go编程. 定义切片     var numbers []int /* 未指定大小 */     /* numbers == []int{0,0,0,0,0}*/     numbers = make([]int,6,6) /* 长度是6容量是6的切片*/ le

python中的切片问题

对于在一个字符串中选取几个字符,不同的语言有不同的解决方案,python 中就有了切片的方法.    在list中,如下:     s=list(range(1,101))    如果想要选取偶数个数字(或者选取偶数),可以用循环的方法:但是方法臃肿,比较"笨"    但是python中给出的切片方法是更加的优雅的,如下:    L=list(range(1,101))    print(L[0])    print(L[0:10])#输出结果是[1, 2, 3, 4, 5, 6, 7

Unity 导出切片精灵

http://blog.csdn.net/akof1314/article/details/38845933 设有一张png/tga图集,导入到Unity,放置目录"Assets/Resources/UI"(UI文件夹可替换成其他的,重要的是要在"Assets/Resources/"路径下),默认为如下设置: 为了可以使用Unity自带的精灵切割,要将纹理类型改成"Sprite","Sprite Mode"改成"Mu

ArcGIS 制作 “地图切片(tile)”

地图切片简介 地图切片,就是将一幅地图切成很多大小一致的小块,调用时候,只有需要的部分才会发送过去,节省带宽的同时,还节省了服务器端实时渲染地图的时间.但是地图切片有一个特点,就是不适合经常变动,或者说实时动态的数据,因为地图切片是地图服务器端事先渲染好的,而且制作地图切片是一个漫长的过程,可以说真的需要很长时间,但是用一次的耗费,换来性能的提升和节省多次渲染的时间是值得的. 切片的示意图如下图,在地图上覆盖这么一个网格,直接切出来.不同之处是,切片可能会分很多级,为了支持在不同缩放级别的显示:

python切片 []取值操作符

切片1.什么叫切片数组,元组等含有多个元素的集合,取其中的一段元素的操作,叫做切片 2.取前10个元素 l = list(range(100)) l3 = l[:10] print(l3) 运行结果: 3.取10到20之间的数据 l = list(range(100)) l3 = l[10:20] print(l3) 运行结果: 4.取倒数第10个以后的数据倒数第一个的index为-1,倒数第二个为-2,以此类推. l = list(range(100)) l3 = l[-10:] print(

python切片

假设有一个list,要对其进行截取操作 L = ['Michael', 'Smith', 'Jobs', 'John'] 首先分别取出其中的值,我们可以像PHP中操作数组一样取值 可见,此种方法可以取出L的值.值得注意的是,索引同PHP Array一样从0开始 如果想取出L中前3个元素,也可以使用for循环来处理 用这种方法,取出了要求的结果.但是python提供了一种更方便简洁的操作,就是切片(slice).下面来演示如果使用切片来获取L中的前三个元素 仅仅用L[0:3]就达到了同for操作一

Python中的切片操作

Python中的切片操作功能十分强大,通常我们利用切片来进行提取信息,进行相关的操作,下面就是一些切片的列子,一起来看看吧,希望对大家学习python有所帮助. 列如我们从range函数1-100中取7的倍数,函数及结果如下所示: >>> for i in range(1,100)[6::7]: print i 7 14 21 28 35 42 49 56 63 70 77 84 91 98 取一个list或tuple的部分元素是非常常见的操作.比如,一个list如下: >>

切图 or 切片

一点题外话: 提到切图,让我想起曾经有好几个月的时间,我每天的主要工作就是切图,或者说切片了. 要制作语文课本中每篇课文的朗读卡拉OK效果,其中一道工序,就是要把文章中的每个字连同上面的拼音,切成单独的一张小图. 一张图上,文字数百上千,纯粹的体力活. 不过这是用fireworks切的片. 今天要说的是用photoshop来切片. 要做一个拼图的小游戏,需要用ps把原图切成长宽一致的15张小图. 1,用ps打开图片 2,在图片上点右键,调出菜单 3,设置水平划分为3,垂直划分为5,则自动划分为1