日期:2014-05-16  浏览次数:20517 次

pctused, pctfree, pctincrease , 行迁移 & 行链接 (转)

关于pctincrease与空间碎片回收的几点看法

?

1.PCTINCREASE>0 的时候SMON 会自动合并表空间中的碎片,等于0的时候只能手工回收

2.PCTINCREASE>0 造成extent不一致甚至可能因为几何增长的缘故造成一个next需要的空间太大

3.固定的next且较小可能造成表的存储段太离散,对查询很不利

?

我的意见是碎片能合并(回收)但是并不等于能利用:

?

而造成碎片的原因是表的存储段离散而extent不一致

一旦PCTINCREASE>0 ,如果next很大则会造成很多问题

你就算能合并碎片,但是这些空间也不能很好的利用,甚至很可能利用率比较低

?

很简单的一个例子:

3+4=7 这是smon合并相临碎片 ,但是这时由于PCTINCREASE>0 的原因,有可能的话,

next extent已经为5了, 那么,7-5=2这部分就几乎永远浪费了(除非重建表空间)

?

所以,尽量保持在表空间所有表的next一致,然后PCTINCREASE=0

这样,就算smon不自动合并临近的碎片,这些碎片也能重复利用

如果能定期的手工合并,那当然也是可以的

?

注意: 这里所说的碎片完全是指表truncate或者drop后释放出来的空间

不是delete后留下来的空间,smon是不能解决delete所浪费的空间?

?

能让表释放空间只有3种情况:

1)drop table.........

2)truncate table .....

3)alter table ..... deallocate unused? 改变表的高水位

?

如果在表里删除一些行,然后往这个表里insert,当然会利用delete出来那些空间

为什么delete不能释放空间?

道理很简单,oracle下为对象分配存储空间是以extent作单位的,你删除的行可能是梅花插竹互相隔离的,如果每个block都有一些行删除了,也有一些没删除的,你要oracle怎么释放(块是操作最小单位)?如果每次delete的时候都要oracle去检查一下有没有一个完整的范围可以释放,这又要消耗额外的性能,而且是没必要的(因为能释放的机会太低了)

?

SMON 合并相邻碎片只针对tablespace的default storage。不针对table storage .

?

?

?

?

?

pctused =40 , 实际使用空间<40%时才加入空闲列表。

pctfree =10 , 插入数据到剩余空间只有10%时 , 不能在该块插入数据。?


?许多新手对于一个块重新回到freelists后的处理都有些误解。其实,一旦由于一个删除的操作而令块被重新加入到freelist中,它将会一直保留在freelist中即使空间的使用超过了60%,只有在到达pctfree时才会将数据块由freelist中移走。


有效地使用空间和高性能之间是有矛盾的,而表格的存储参数就是控制这个方面的矛盾:

?? ?. 对于需要有效地重新使用空间,可以设置一个高的pctused值,不过副作用是需要额外的I/O。一个高的pctused值意味着相对满的块都会放到freelist中。因此,这些块在再次满之前只可以接受几行记录,从而导致更多的I/O。

?

?? ?. 追求高性能的话,可以将pctused设置为一个低的值,这意味着Oracle不会将数据块放到freelists中直到它几乎是空的。那么块将可以在满之前接收更多的行,因此可以减少插入操作的I/O。要记住Oracle扩展新块的性能要比重新使用现有的块高。对于Oracle来说,扩展一个表比管理freelists消耗更少的资源。




行链接: 行链接产生在第一次插入数据的时候如果一个block不能存放一行记录的情况下。

、这种情况下,Oracle将使用链接一个或者多个在这个段中保留的block存储这一行记录,

比较容易发生在比较大的行上。比如Long, LOB等。

只能增大 db_block_size 来清除行链接 。

?

行迁移: 当一行记录初始插入的时候事可以存储在一个block中的,由于更新操作导致行长增加了

,而block的自由空间已经完全满了,这个时候就产生了行迁移。在这种情况下,Oracle将会迁移整

行数据到一个新的block中(假设一个block中可以存储下整行数据),Oracle会保留被迁移行的原始

指针指向新的存放行数据的block,这就意味着被迁移行的ROW ID是不会改变的。

pctfree设置过小是导致行迁移的一个原因。设置太大可能导致空间利用率低下 。


让我们来回顾一下设置对象存储参数的一些常见规则:

?? ?.经常将pctused设置为可以接收一条新行(足够小)。对于不能接受一行的free blocks对于我们来说是没有用的。如果这样做,将会令Oracle的性能变慢,因为Oracle将在扩展表来得到一个空的块之前,企图读取5个"dead"的free block。

?

?? ?.表格中chained rows的出现意味着pctfree太低。在很多情况下,RAW和LONG RAW列都很巨大,以至超过了Oracle的最大块的大小,这时chained rows是不可以避免的。

?

?? ?.freelist参数应该设置为表格同时更新的最大值。例如,如果在任何时候,某个表最多有20个用户执行插入的操作,那么该表的参数应该设置为freelists=20。

?

?? ?应记住的是freelist groups参数的值只是对于Oracle Parallel Server和Real Application Clusters才是有用的。对于这类Oracle,freelist groups应该设置为访问该表格的Oracle Parallel Server实例的数目。