Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3583483
  • 博文数量: 109
  • 博客积分: 10011
  • 博客等级: 上将
  • 技术积分: 2457
  • 用 户 组: 普通用户
  • 注册时间: 2006-10-18 19:04
文章分类

全部博文(109)

文章存档

2011年(1)

2010年(10)

2009年(36)

2008年(62)

我的朋友

分类: Oracle

2009-08-31 10:05:19

一:段:
   ORACLE中段是占用磁盘存储空间的一个对象,而不是一个逻辑定义,常用的段有:
1)表 和表分区 2)聚簇(cluster) 3)索引 和索引分区 4)lob分区 5)嵌套表 6)回滚段。
表和表分区虽然是两种segment类型,但是本质是一样的,索引和索引分区也是两种segment类型,但是本质也是一样的。
   我们通常使用的表或索引其实只是一个逻辑定义,而不是实际的物理段,表或索引可能由多个表分区或者索引分区组成,每个表分区或者索引分区一定是一个段。表可以存在于一个表段,也可以存在于一个叫聚簇(cluster)的段中。在一个大表中,特别是在OLAP的DW系统中,对表做分区和对索引做分区是一个很平常而且很重要的工作。
综上所说,表在不分区的情况下是一个段,在分区的情况下,表存储在多个段中,索引也是一样。
SQL> conn segment_study/liugao;
已连接。
SQL> select segment_name, segment_type
  2    from user_segments;
未选定行
SQL> create table t ( x int primary key, y clob, z blob );
表已创建。
SQL> select segment_name, segment_type
  2    from user_segments;
SEGMENT_NAME SEGMENT_TYPE
------------------------------ ------------------
SYS_IL0000063631C00002$$ LOBINDEX
SYS_LOB0000063631C00003$$ LOBSEGMENT
SYS_C009783 INDEX
SYS_IL0000063631C00003$$ LOBINDEX
SYS_LOB0000063631C00002$$ LOBSEGMENT
T TABLE
已选择6行。
   实际上,表T本身创建了一个段,主键创建了一个index段,lob类型比较特殊,每一个lob字段,都要建立各自单独的lob段,并且有相应的lobindex跟踪LOB的块在哪里。
 
 
二:高水位线
   在引入高水位线之前,我先介绍一下段空间管理,在Oracle 9i 以前,ORACLE都是手动段空间管理,有很多复杂的参数配置,比如FREELISTS等,这些配置如果没做好,对性能产生致命的影响,ORACLE 9i 以后,引入了ASSM,自动段空间管理,只需要设置4个参数。BUFFER_POOL,PCTFREE,INITRANS,MAXFTRANS 。我会在以下的文章中讲到这四个参数的配置方法。
   高水位线就是数据块曾经达到的最大的位置。为什么说曾经呢,因为高水位线是只增不减,只升不降的。直到这个segment被truncate。
   因为Oracle在全面扫描段时会扫描HWM之下的所有块,即使其中不包含任何数据。这会影响全面扫描的性能,特别是当HWM之下的大多数块都为空时。要查看这种情况,只需创建一个有1,000,000行的表(或者创建其他有大量行的表),然后对这个表执行一个SELECT COUNT(*)。 下面再删除(DELETE)这个表中的每一行,你会发现尽管SELECT COUNT(*)统计出0行,但是它与统计出1,000,000所花的时间一样长(如果需要完成块清除,时间可能还会更长。这是因为Oracle在忙于读取HWM之下的所有块,查看其中是否包含数据。如果对这个表使用TRUNCATE而不是删除其中的每一行,你可以比较 一下结果有什么不同。TRUNCATE会把表的HWM重置回“0”,还会截除表上的相关索引。由于以上原因,如果你打算删除表中的所有行,就应该选择使用 TRUNCATE(如果可以使用的话)。
   那么怎么解决这个问题呢?在手动段空间管理的情况下,必须手动调整freelist,但是在自动的段空间管理情况下,这个问题ORACLE已经处理了,这也是ASSM的一个主要左右之一:不必手动地确定许多关键存储参数的正确设置。
 
 
三:行迁移
   在引入行迁移之前,我先介绍一下两个重要的参数:PCTFREE,PCTUSED.首先要明确,OR这两个参数是对ORACLE最小存储空间:块(block)的设置,设置的百分数都是指定一个块内的百分数。ORACLE中被使用的块的空间不是全部都存储了数据。比如说db_block_size为8k,并不能存储8k的数据。
   PCTFREE参数用来告诉Oracle应该在块上保留多少空间来完成将来的更新。默认情况下,这个值是10%。如果自由空间的百分比高于 PCTFREE中的指定值,这个块就认为是“自由的”。PCTUSED则告诉Oracle当前不“自由”的一个块上自由空间百分比需要达到多大才能使它再次变为自由的。默认值是40%。
   使用ASSM时,PCTFREE仍然会限制能否将一个新行插入到一个块中,但是它不会控制一个块是否在freelist上,因为ASSM根本不使用freelist。在ASSM中,PCTUSED将被忽略。这就是为什么我在上面说的4个参数里面没有PCTUSED的原因。
PCTFREE有3 种设置:太高、太低和刚好。如果把块的PCTFREE设置得过高,就会浪费空间。如果把PCTFREE设置为50%,而你从未更新数据,那么每个块都会浪 费50%的空间。不过,在另一个表上,50%可能非常合理。因为在改变行的大小的时候,行已经确定在哪个BLOCK里了,如果行初始很小,现在想将行的大小加倍,但是倘若PCTFREE设置得太小,不足以存储行加倍需要的容量,更新行时就会导致 行迁移。
   行迁移会导致性能问题。在通过索引查询时,索引找到某一行对应的一个块,这样就可以得到这一行数据,如果有行迁移,必须多执行一次I/O操作才可以得到一行数据,单独一次操作问题不大,但是在多用户并发读取同一行时,性能问题就会显现出来。
   所以,现在我们再回到PCTFREE,来说明这个参数的作用:如果设置得当,这个参数可以帮助你尽量减少行串链。
   又引出一个问题。怎样设置PCTFREE和PCTUSED值??
 需要按照应用的需要来灵活设置了。
 1)高PCTFREE,低PCTUSED:如果你插入了将要更新的大量数据,而且这些更新会频繁地增加行的大小,此时就适合采用这种设置。
 2) 低PCTFREE,高PCTUSED:如果你只想对表完成INSERT或DELETE,或者如果你确实要完成UPDATE,但UPDATE只是缩小行的大小,此时这种设置就很适合。 在数据仓库系统中,比较适合,PCTFREE可以设置得很低,因为几乎没有更新操作。
 
 

 
阅读(1834) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~