段的类型
1)表段
2)表分区段(table partition)或子分区段(subpartition)
这种段类型用于分区,与表段很相似。分区表由一个或多个分区段(table partition segment)组成,组合分区表则由一个或多个表子分区段(tablesubpartition segment)组成。
3)聚簇段(cluster)
“聚簇”是指这个段能把相关的信息物理的聚在一起。有两种类型的聚簇:B*树聚簇和散列聚簇。
4)索引段(index)
5)索引分区(index partition)
类似与表分区,这种段类型包含一个索引的某个片。分区索引由一个或多个索引分区段(index partition segment)组成。
6)lob段(lobsegment),lob索引段(lobindex),Lob分区段(lob partition)、lob子分区段(lob subpartition)
用于保存大对象 (large object或LOB)。
7)嵌套表段(nested table)
为嵌套表指定的段类型。
8)回滚段(rollback)和Type2 undo段
undo数据就存储在这里。回滚段是DBA手动创建的段。Type2 undo段由Oracle自动创建和管理。
创建表时,会创建一个表段。创建分区表时,则每个分区会创建一个段。创建索引时,就会创建一个索引段,依此类推。
例如 create table t( x int primary key, y clob) 这样一个简单的语句就会创建4个段:
一个是TABLE T的表段;
一个是索引段(这个索引是为支持主键而创建的);
另外还有两个CLOB段(一个是LOB 索引,另一个段是LOB数据本身)。
11g Release2之后,默认情况下,段会延迟到插入第一行数据之后才创建。也可以用下面语句在创建表格同时就创建段。
create table t( x int primary key, y clob) segment creation immediate;
段空间管理
段空间管理是从段的表空间(而且段从不会跨表空间)继承来的一个属性。使用CREATE TABLESPACE语句创建一个本地管理的表空间时,可以使用 SEGMENT SPACE MANAGEMENT 子句来设定段内的可用/已用空间如何管理。
1)手动段空间管理(Manual Segment Space Management,MSSM)
Oracle 使用可用块列表(free list)来管理段内的可用空间。可用块列表记录了所有可以被用于插入新数据的数据块。
2)自动段空间管理(Automatic Segment Space Management,ASSM)
Oracle 使用位图(bitmap)管理段内的可用空间。[注意此处的位图与本地管理的表空间使用的位图不一样]此处的位图用于描述段内每个数据块是否有足够的可用空间来插入新数据。随着一个数据块中可用空间的变化,她的状态也被及时地反映到位图中。Oracle 使用位图可以更自动化地管理段内的可用空间。
应用于ASSM的存储设置参数只有:
· BUFFER_POOL
· PCTFREE
· INITRANS和MAXTRANS(->http://blog.csdn.net/fw0124/article/details/6899223)
创建段时也可以接受其他参数,但是这些参数将被忽略。
高水位线
在段中有一个高水位线(high-water mark,HWM)。如果把段想象成从下到上的一系列的块,HWM代表包含了数据的最上面的块。
HWM首先位于新创建表的第一个块中。在这个表中插入数据后,HWM会升高。如果我们删除了表中的一些(甚至全部)行,HWM也不会降低。这样就可能会有许多块不再包含数据,但是它们仍在HWM之下,直到重建、截除(TRUNCATE)或收缩这个段。
(段收缩是Oracle 10g的一个新特性,只有当段在一个ASSM表空间中时才支持这个特性,通过下述语句
alter table t enable row movement; alter table t shrink space;
可以在一个表格上执行段收缩)
因为Oracle在全面扫描段时会扫描HWM之下的所有块,即使其中不包含任何数据,这会影响全面扫描的性能,特别是当HWM之下的大多数块都为空时。所以删除表中所有行的时候,如果可能就使用TRUNCATE。
在ASSM表空间中,除了一个HWM外,还有一个低HWM。在MSSM中,HWM推进时 (例如,插入行时。段分配空间时以区段(extent)为单位,一个区段包括很多物理连续的块),所有块都会被格式化并立即有效,Oracle可以安全地读取这些块。不过,对于ASSM,HWM推进时,Oracle并不会立即格式化所有块,只有在第一次向这些块插入记录时才会完成格式化,以便安全地读取。对于ASSM,数据可能插入到高水位和低水位之间的任意块,因此这个区域中的很多块都不会被格式化。全面扫描时,需要知道读取的块是否未格式化,为了避免段中每个块都要做检查,Oracle对低水位以下的所有块都会直接读取,低水位和高水位之间的块则需要参考ASSM的块位图信息来查看哪些块应该读取,哪些应该忽略。
FREELIST
使用MSSM时,Oracle会在FREELIST中维护HWM以下,可供用来插入数据的块。如果预计到会有多个并发用户在一个对象上执行大量的INSERT或UPDATE活动,就可以配置多个FREELIST,这对性能提升很有好处。
PCTFREE和PCTUSED
PCTFREE参数用来告诉Oracle应该在块上保留多少空间来完成将来的更新。默认情况下,这个值是10%。如果未用空间的百分比高于PCTFREE中的指定值,这个块就认为是“可用”,可以用来插入数据。
PCTUSED则告诉Oracle当前已经变成“不可用”的一个块上未用空间百分比需要达到多大(由于删除,更新等释放了空间)才能使它再次变为"可用"的。默认值是40%。
使用MSSM时,这2个参数控制着块何时放入FREELIST中,以及何时从FREELIST中取出。如果使用默认值:PCTFREE为10,PCTUSED为40,那么在块到达90%满之前(有10%以上的自由空间),这个块会一直在FREELIST
上。一旦到达90%满,就会从FREELIST中取出,而且直到块上的自由空间超过了块的60%时,才会重新回到FREELIST上。
使用ASSM时,PCTFREE仍然会限制能否将一个新行插入到一个块中,但是PCTUSED将被忽略。
PCTFREE设置太大,则会浪费空间;设置太小,更新行时就会导致行迁移。
行迁移(row migration)是指由于某一行变得太大,导致块中已经放不下这一行,Oracle 将此行数据迁移(migrate)到新的数据块中,在被迁移数据行原来所在位置保存一个指向新数据块的指针。被迁移数据行的ROWID保持不变。行迁移会影响性能,必须执行更多的I/O才能得到行数据。
行链接(row chaining)发生在插入数据时,如果一个block不能存放下一行记录,Oracle将使用链接多个block存储这一行记录,如果行比较大,容易发生。
可以使用analyze table xxx list chained rows 命令来分析表格中的行链接或者行迁移。
为此需要先建立chained_rows表格。
首先执行$ORACLE_HOME/RDBMS/ADMIN/utlchain.sql脚本建立chained_rows表格,
然后执行analyze table xxx list chained rows [into chained_rows],
如果存在行链接或者行迁移,查询chained_rows就能找到发生了行链接或者行迁移的行。