数据库块(database block)是ORACLE逻辑分配空间的最底层,又称逻辑块、页或ORACLE块。
数据库块是数据库使用和分配空间的最小单元,也可以说是使用的最小I/O单元,一个数据块与磁盘上指定的物理空间大小相一致,一个数据库块对应一个或多个物理块,块的大小由参数db_block_size确定。
PCTFREE和PCTUSED是开发人员用来控制数据块中可用插入和更新数据的空闲空间大小的参数。
PCTFREE:设置数据块中保持空闲的百分比。
PCTUSED:当数据块空闲空间达到PCTFREE时,此块不允许插入数据,只能修改或删除块中的行,更新时可能使数据块空闲空间变大,已用数据空间变小,当已用空间低于PCTUSED时,则可以重新插入数据。
PCTFREE及PCTUSED的选择:
经常做查询(select)的表,应使PCTFREE小些,尽量减少存储空间浪费。
经常做插入(insert)的表,应使PCTUSED大一些。
经常做更新(update)的表,应使PCTFREE大一些,给更新留出更大的空间,减少行移动。
PCTFREE:块中保留用于Update操作的空间百分比,当数据占用的空间达到此上限时,新的数据将不能再插入到此块中;
PCTFREE存储参数告诉ORACLE什么时候应该将数据块从对象的空闲列表中移出。ORACLE的默认参数是PCTFREE=10;也就是说,一旦一个Insert操作使得数据块的90%被使用,这个数据块就从空闲列表(free list)中移出。
PCTUSED:指定块中数据使用空间的最低百分比;当一个块在达到PCTFREE,之后经历了一些Delete操作,在其空间使用下降到PCTUSED后便可以重新被用于Insert数据;
PCTUSED存储参数告诉ORACLE什么时候将以前满的数据块加到空闲列表中。当记录从数据表中删除时,数据库的数据块就有空间接受新的记录,但只有当填充的空间降到PCTUSED值以下时,该数据块才被连接到空闲列表中,才可以往其中插入数据。PCTUSED的默认值是PCTUSED=40。
调整PCTFREE、PCTUSED参数的目标一方面是提高性能,另一方面则主要是提高空间使用效率,避免出现块中存在有许多未用的空间,但却无法找到一个块可以被用于插入新数据行的情况发生。
PCTFREE的使用
在Oracle中表的每一行数据由唯一的ROWID标记;而Oracle支持的数据类型中有一些长度是可变的,如VARCHAR,当对这些数据进行Update时,如果块中的可用空间不能容纳Update后的数据行时,Oracle将会把此行移到其它数据块,同时保留此数据行的ROWID不变,并在原有块中建一指针指向行迁移后的位置。在这种情况下读取一行数据将需要访问2个数据块,从而导致性能下降。PCTFREE保留的空间就是为确保更改后的数据行可以仍存放于原有数据块中,避免行迁移的情况发生。 由此,如果PCTFREE设置不足时可能产生行迁移;而另一方面如果PCTFREE设置过高,将会造成空间浪费。因此正确设置PCTFREE需要对表中数据的使用进行分析。对于数据长度不会变化或极少更新的情况,可以采用较小的PCTFREE;对于其它大多数情况应采用稍大的PCTFREE(PCTFREE的缺省值是10,如果不好估计需预留的空间,可以使用15-25的范围),不要为节约块中的空间而使用较小的PCTFREE值。
PCTUSED的使用
当块的使用的空间下降到PCTUSED后,此块被重新放回空闲链表(Freelist)中,作为后续Insert的候选块。同样,设置PCTUSED需要视数据行的特性和Insert、Update、Delete的模式而定,但必须遵守的原则是:db_block_size * (100 – PCTFREE – PCTUSED)必须比行的长度大。 对于数据行长度变化较大的情况,应使用最大行长度来计算PCTUSED,并且应使用较低的PCTUSED值。因为在执行Insert时,如果数据块的可用空间不能装下一行数据,当块的使用的空间是在PCTUSED之上,Oracle将把此块从Freelist中移走;当块的使用的空间是在PCTUSED之下,Oracle将会扩展段空间。因此,PCTUSED如果设得过高,将导致段的不断扩展。 当数据行长度不大时,使用缺省的PCTUSED(40)是比较合适的;对于行长度较大的情况,最长的行有可能会占用半个以上的块空间,此时可设置PCTUSED为10。较小的PCTUSED仅在表中的数据以随机方式被删除,而且仍有一些行长时间保留在块中时,才会造成空间使用上的问题,因为这些块可能需要较长的时间才能或永远不能重新被用于存放新数据。在这种应用中,如果空间利用率一直处于较低水平,则需对PCTUSED进行分析和调整。
PCTUSED较高意味着相对较满的数据块会被放置到空闲列表中,从而有效的重复使用数据块的空间,但会导致I/O消耗。PCTUSED低意味着在一个数据块快空的时候才被放置到空闲列表中,数据块一次能接受很多的记录,因此可以减少I/O消耗,提高性能。
PCTFREE的值较大意味着数据块没有被利用多少就从空闲列表中断开连接,不利于数据块的充分使用。PCTFREE过小的结果是,在更新时可能会出现数据记录迁移(Migration)的情况。(注:数据记录迁移(Migration)是指记录在是Update操作扩展了一个VARCHAR2类型的列或BLOB列后,PCTFREE参数所指定的空间不够扩展,从而记录被ORACLE强制迁移到新的数据块,发生这种情况将较严重的影响ORACLE的性能,出现更新缓慢)。
举例说明:PCTFREE参数是控制freelist un-links的(即将块由freelists中移除)。设置PCTFREE=10 意味着每个块都保留10%的空间用作行扩展。PCTUSED参数是控制freelist re-links的。设置PCTUSED=40意味着只有在块的使用低于40%时才会回到表格的freelists中。
可通过查询dba_tables/dba_clusters/dba_indexes表查看当前设置的值。
对于永远不会做变动的表,可以把PCTFREE设置为0,以最大限度的利用空间。
参考文档:http://www.towiyo.com/blog/index.php/category/oracle/oracle-op/
http://www.51testing.com/?uid-2047-action-spacelist-type-blog-itemtypeid-11642