再上一篇:9.6小结
上一篇:10.1表类型
主页
下一篇:10.3堆组织表
再下一篇:10.4索引组织表
文章列表

10.2术语

Oracle 9i 10g编程艺术:深入数据库体系结构

在 这一节中,我们将介绍与表相关的各种存储参数和术语。并非每种表类型都会用到所有参数。例 如,PCTUSED参数在IOT环境中就没有意义。具体讨论各种 表类型时还会分别介绍与之相关的参数。这一 节的目标时介绍这些术语,并给出定义。在后面几节中,还会在适当的时候介绍使用特定参数的更多信息。

10.2.1段

Oracle中的段(segment)是占用磁盘上存储空间的一个对象。尽管有多种类型,不过最常见的段类 型如下:
q 聚簇(cluster):这种段类型能存储表。有两种类型的聚簇:B*树聚簇和散列聚簇。聚 簇通常用于存储多个表上的相关数据,将其“预联结”存储到同一个数据库块上;还可以用于 存储一个表的相关信息。“聚簇”这个词是指这个段能把相关的信息物理的聚在一起。
q 表(table):表段保存一个数据库表的数据,这可能是最常用的段类型,通常与索引段 联合使用。
q 表 分区(table partition)或子分区(subpartition):这种段类型用于分区,与表段 很相似。分区表由一个或多个分区段(table partition segment)组成,组合分区表则由一个 或多个表子分区段(table subpartition segment)组成。
q 索引(index):这种段类型可以保存索引结构。
q 索引分区(index partition):类似与表分区,这种段类型包含一个索引的某个片。分 区索引由一个或多个索引分区段(index partition segment)组成。
q Lob分 区(lob partition)、lob子分区(lob subpartition)、lob索引(lobindex) 和lob段(lobsegment):lobindex和lobsegment段保存大对象 (large object或LOB)的 结构。对包含LOB的表分区时,lobsegment也会分区,lob分区段(lob partition segment) 正是用于此。有意思的是,并没有一种lobindex分区段(lobindex partition segment)类型
——不论出于什么原因,Oracle将分区lobindex标记为一个索引分区(有人很奇怪为什么要另 外给lobindex取一个特 殊的名字!)。
q 嵌套表(nested table):这是为嵌套表指定的段类型,它是主/明细关系中一种特殊类 型的“子”表,这种关系随后将详细讨论。
q 回滚段(rollback)和Type2 undo段:undo数据就存储在这里。回滚段是DBA手动创建 的段。Type2 undo段由Oracle自动创建和管理。
举 例来说,一个表可以是一个段。索引有可能是一个段。这里我强调了“可能”,这是因为,我们 可以把一个索引划分到不同的段中。所以,索引对象本身只是一个定 义,而不是一个物理段,索引可能由 多个索引分区组成,而每个索引分区(index partition)是一个段。表可能是一个段,也可能不是。由于 同样的原因,由于表分区,一个表可以有多个表段:或者可以在一个称为聚簇的段中创建一个 表,此时这 个表可能与其他表同在一个聚簇段中。
不 过,最常见的情况是,表是一个段,索引也是一个段。对现在来说,这样考虑最简单。创建一个 表时,通常就是创建一个新的表段,而且如第3章所述,这个段包含 区段,区段则包含块。这是平常的存 储层次结构。但是要指出重要的一点,只在“通常”情况下才有这种一对一的关系。例如,考虑以下这个 简单的CREATE TABLE语句:

Create table t ( x int primary key, y clob, z blob );
这个语句创建6个段。如果在一个初始为空(什么也没有)的模式中发出下面的CREATE TABLE语句, 会观察到以下结果:

ops$tkyte@ORA10G> select segment_name, segment_type
2 from user_segments;
no rows selected
ops$tkyte@ORA10G> create table t ( x int primary key, y clob, z blob ); Table created.
ops$tkyte@ORA10G> 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 rows selected. 在这个例子中,表本身创建了一个段:如输出中最后一行所示。这里主键约束创建了一个索引段,以
保证惟一性。
注意 惟一约束或主键可能创建一个新索引,也可能不创建。如果约束列上已经有一个索引,而且这些列处于 索引的前几列,这个约束就会(而且将会)使用这些列(而不再创建创建新索引)。
另外,每个LOB列分别创建了两个段:一个段用于存储字符大对象(character large object, CLOB) 或二进制大对象(binary large object, BLOB)所指的实际数据块,另一个段用于“组织”这些数据块。
LOB为非常大块的信息提供了支持,可以多达几GB。LOB存储在lobsegment的块中,lobindex用于跟踪这 些LOB块在哪里,以及应该以何种顺序来访问它们。

10.2.2段空间管理

从Oracle 9i开始,管理段空间有两种方法:
q 手 动段空间管理(Manual Segment Space Management):由你设置 FREELISTS、FREELIST GROUPS、PCTUSED和其他参数来控制如何分配、使用和重用段中的空间。在这一章中我会把这种 空间管理方法称为MSSM,但是要记住,这是一个我 自造的缩写,Oracle文档中没有这个缩写。
q 自动段空间管理(Automatic Segment Space Management, ASSM):你只需控制与空间使 用相关的一个参数:PCTFREE。创建段时也可以接受其他参数,但是这些参数将被忽略。
MSSM是Oracle的遗留实现。它已经存在多年,许多版本都支持MSSM。ASSM则在Oracle 9i Release 1 中 才首次引入。原先用于控制空间分配和提供高并发性的参数数不胜数,并且需要对这些参数进行调整, 人们不希望还要这么做,这正是设计ASSM的出发点。例 如,倘若将FREELISTS参数设置为默认值1,可 能会出现,如果你的段是插入/更新新密集的(有大量插入/更新操作),对自由空间的分配就会存在竞 争 。 Oracle要在表中插入一行,或更新一个索引键条目,或者由于更新一行而导致这一行迁移时(稍后还会更 多地介绍这方面的内容),可能需要从与这个段 相关的自由块列表中得到一个块。如果只有一个自由块列 表,一次就只有一个事务能查看和修改这个列表,事务之间必须相互等待。在这种情况下,如果有多个 FREELISTS和FREELIST GROUPS,就能提高并发性,因为事务可以分别查看不同的列表,而不会相互竞争。
稍后讨论存储设置时,我还会提到哪些参数用于手工段空间管理,而哪些参数用于自动段空间管理, 不过需要指出,在存储/段特征这方面,应用于ASSM段的存储设置只有:
q BUFFER_POOL
q PCTFREE
q INITRANS
q MAXTRANS(仅用于9i;在10g中,所有段都会忽略这个参数) 其他存储和物理属性参数都不适用于ASSM段。
段空间管理是从段的表空间(而且段从不会跨表空间)继承来的一个属性。段要使用ASSM,就必须 位于支持ASSM空间管理的表空间中。

10.2.3高水位线

存储在数据库中的表段使用了这个术语。例如,如果把表想象成一个“平面”结构,或者想象成从左 到右依次排开的一系列块,高水平线(high-water mark,HWM)就是包含了数据的最右边的块,如图10-
1所示。

图10-1 HWM示意图
图10 -1显示了HWM首先位于新创建表的第一个块中。过一段时间后,随着在这个表中放入数据, 而且使用了越来越多的块,HWM会升高。如果我们删除了表中的一 些(甚至全部)行,可能就会有许多块 不再包含数据,但是它们仍在HWM之下,而且这些块会一直保持在HWM之下,直到重建、截除或收缩这个 对象(将段收缩 是Oracle 10g的一个新特性,只有当段在一个ASSM表空间中时才支持这个特性)。
HWM很重要,因为Oracle在全面扫描段时会扫描HWM之下的所有块,即使其中不包含任何数据。这 会影响全面扫描的性能,特别是当HWM之下的大多数块都为空时。要查看这种情况,只需创建一个有
1,000,000行的表(或者创建其他有大量行的表),然后对这个表执行一个SELECT COUNT(*)。 下面再删 除(DELETE)这个表中的每一行,你会发现尽管SELECT COUNT(*)统计出0行,但是它与统计出1,000,000 所花的时间一样长(如果需要完成块清除,时间可能还会更长:有关内容请参加 9.5.5 节)。这是因为 Oracle 在忙于读取HWM之下的所有块,查看其中是否包含数据。如果对这个表使用TRUNCATE而不是删除其中的每 一行,你可以比较 一下结果有什么不同。TRUNCATE会把表的HWM重置回“0”,还会截除表上的相关索引 。 由于以上原因,如果你打算删除表中的所有行,就应该选择使用 TRUNCATE(如果可以使用的话)。
在 一个MSSM表空间中,段只有一个HWM。不过,在ASSM表空间中,除了一个HWM外,还有一个低 HWM(见图10-2)。在MSSM中,HWM推进时 (例如,插入行时),所有块都会并立即有效,Oracle可以 安全地读取这些块。不过,对于ASSM,HWM推进时,Oracle并不会立即格式化所有 块,只有在第一次使 用这些块时才会完成格式化,以便安全地读取。所以,全面扫描一个段时,必须知道要读取的块是否“安 全”或是否格式化,(这说明,其中不 包含有意义的信息,不能对其进行处理)。为了避免表中每一个块 都必须经过这种安全/不安全检查,Oracle同时维护了一个低HWM和一个HWM。 Oracle会全表扫描至HWM, 对于低HWM以下的所有块会直接读取并加以处理。而对介于低HWM和HWM之间的块,则必须更加小心,需 要参考管理这些 块所用的ASSM位图信息来查看应该读取哪些块,而哪些块应该被忽略。

图 10-2 低HWM示意图

10.2.4 freelists

使用MSSM表空间时,Oracle会在自由列表(freelist)中为有自由空间的对象维护HWM一些的块。 注意 freelists组和freelist组在ASSM表空间中根本就没有;仅MSSM表空间使用这个技术。
每 个对象都至少有一个相关的freelist,使用块时,可能会根据需要把块放在freelist上或者从 freelist删除。需要说明的重要一点是,只 有位于HWM以下的对象块才会出现在freelist中。仅当 freelist为空时才会使用HWM之上的块,此时Oracle会推进HWM,并把这些块 增加到freelist中,采用 这种方式,Oracle会延迟到不得已时才增加对象的HWM。
一个对象可以有多个freelist。如果预计到会有多个并发用户在一个对象上执行大量的INSERT或 UPDATE活动,就可以配置多个freelist,这对性能提升很有好处(但是可能要以额外的存储空间为代价)。 根据需要配置足够多的freelist非常重要。
如果存在多个并发的插入和更新,在这样一个环境中,FREELISTS可能对性能产生巨大的影响(可能 是促进,也可能是妨碍)。通过一个极其简单的测试就能看出正确地设置FREELISTS有什么好处。请考虑 下面这个相对简单的表:

ops$tkyte@ORA10GR1> create table t ( x int, y char(50) ) tablespace MSSM;
Table created.
接 下来使用5个并发会话,开始“疯狂地”对这个表执行插入。如果分别测量插入前和插入后与块 相关的系统级等待事件,就会发现长时间的等待,特别是对数据块的 等待(试图插入数据)。这通常是因 为表(以及索引)上的freelist不足造成的(不过关于索引的有关内容将在下一章更详细介绍)。为此我 使用了 Statspack,首先取一个statspace.snap,接下来执行一个脚本开始5个并发的SQL*Plus会话, 等这些会话退出后再取另一个 statspace.snap。这些会话运行的脚本很简单,如下:

begin
for i in 1 .. 100000 loop
end;
end loop;
commit;
insert into t values ( i, 'x' );

/
exit;
这 是一个非常简单的代码块,此时我是数据库中惟一的用户。按理说,应该得到最佳的性能,因为 我配置了充足的缓冲区缓存,重做日志大小很合适,另外索引也不会 减慢速度,而且这是在有两个超线程 Xeon CPU的主机上运行,这个主机应该能运行得很快。不过,我看到的结果却是:

Snap Id Snap Time Sessions Curs/Sess
Comment
--------- ------------------ --------
--------- -------------------
Begin Snap: 793 29-Apr-05 13:45:36 15 3.9
End Snap: 794 29-Apr-05 13:46:34 15 5.7
Elapsed: 0.97 (mins) Top 5 Timed Events
~~~~~~~~~~~~~~~~~~
% Total
Event Waits Time
(s) Call Time
-------------------------------------------- ------------ -----------
-------------
CPU time
165 53.19
buffer busy waits 368,698 119
38.43
log file parallel write 1,323 21
6.86
latch: cache buffers chains 355 2
.67
enq: HW - contention 2,828 1
.24
对buffer busy waits总共等待了119秒,也就是每个会话大约24秒。导致这些等待的原因完全是: 表中没有配置足够的freelist来应付发生的这种并发活动。不过,只需将表创建为有多个freelist,就 能轻松地消除大部分等待时间:

ops$tkyte@ORA10GR1> create table t ( x int, y char(50) )

2 storage( freelists 5 ) tablespace MSSM; Table created.
或者也可以通过修改对象达到目的:

ops$tkyteORA10GR1> alter table t storage ( FREELISTS 5 );
Table altered.
你会看到,buffer busy waits大幅下降,而且所需的CPU时间也随着耗用时间的下降而减少(因为

这里做的工作更少;对闩定数据结构的竞争确实会让CPU焦头烂额):
Comment
Snap Id Snap Time Sessions Curs/Sess
--------- ------------------ --------
--------- -------------------
Begin Snap: 809 29-Apr-05 14:04:07 15 4.0
End Snap: 810 29-Apr-05 14:04:41 14 6.0
Elapsed: 0.57 (mins)
Top 5 Timed Events
~~~~~~~~~~~~~~~~~~
% Total
Event Waits Time
(s) Call Time
-------------------------------------------- ------------ -----------
---------
CPU time 122
74.66
buffer busy waits 76,538 24
14.94
log file parallel write 722 14
8.45
latch: cache buffers chains 144 1
.63
enq: HW - contention 678 1
.46
对 于一个表来说,你可能想确定最多能有多少个真正的并发插入或更新(这需要更多空间)。这里 我所说的“真正的并发”是指,你认为两个人在同一时刻请求表中一 个自由块的情况是否频繁。这不是对 重叠事务的一种量度;而是量度多少个会话在同时完成插入,而不论事务边界是什么。你可能希望对表的 并发插入有多少, freelist就有多少,以此来提高并发性。
只 需把freelist设置得相当高,然后就万事大吉了,是这样吗?当然不是,哪有这么容易。使用多 个freelist时,有一个主freelist,还有 一些进程freelist。如果一个段只有一个freelist,那么主 freelist和进程freelist就是这同一个自由列表。如果你有两个 freelist,实际上将有一个主freelist 和两个进程freelist。对于一个给定的会话,会根据其会话ID的散列值为之指定一个进程 freelist。目 前,每个进程freelist都只有很少的块,余下的自由块都在主freelist上。使用一个进程freelist时 , 它会根据需 要从主freelist拉出一些块。如果主freelist无法满足空间需求,Oracle就会推进HWM,并 向主freelist中增加空块。过一段时 间后,主freelist会把其存储空间分配多个进程freelist(再次 说明,每个进程freelist都只有为数不多的块)。因此,每个进程会使用 一个进程freelist。它不会从 一个进程freelist到另一个进程freelist上寻找空间。这说明,如果一个表上有10个进程 freelist, 而且你的进程所用的进程freelist已经用尽了该列表中的自由缓冲区,它不会到另一个进程freelist上 寻找空间,即使另外9 个进程freelist都分别有5块(总共有 45个块),此时它还是会去求助主freelist。 假设主freelist上的空间无法满足这样一个自由块 请求,就会导致表推进HWM,或者如果表的HWM无法 推进(所有空间都已用),就要扩展表的空间(得到另一个区段)。然后这个进程仍然只使用其 freelist 上的空间(现在不再为空)。使用多个freelist时要有所权衡。一方面,使用多个freelist可以大幅度 提升性能。另一方面,有 可能导致表不太必要地使用稍多的磁盘空间。你必须想清楚在你的环境中哪种做 法麻烦比较小。
不 要低估了FREELISTS参数的用处,特别是在Oracle 8.1.6及以后版本中,你可以根据意愿自由地 将其改大或改小。可以把它修改为一个大数,从而与采用传统路径模式的SQL*Loader并行完成数据的
加 载。这样可以获得高度并发的加载,而只有最少的等待。加载之后,可以再把这个值降低为某个更合理 的平常的数。将空间改小时,现有的多个freelist上 的块要合并为一个主freelist。
要解决前面提到的缓冲区忙等待问题,还有一种方法,这就是使用一个ASSM管理的表空间。还是前 面的例子,但在ASSM管理的表空间中要如下创建表T:

ops$tkyte@ORA10GR1> create tablespace assm
2 datafile size 1m autoextend on next 1m
3 segment space management auto; Tablespace created.
ops$tkyte@ORA10GR1> create table t ( x int, y char(50) ) tablespace ASSM; Table created.
你会看到,在这种情况下,缓冲区忙等待、CPU时间和耗用时间都会下降,在此不必确定最好要有多 少个freelist:
Comment

Snap Id Snap Time Sessions Curs/Sess
--------- ------------------ --------
--------- -------------------

Begin Snap: 812 29-Apr-05 14:12:37 15 3.9
End Snap: 813 29-Apr-05 14:13:07 15 5.6
Elapsed: 0.50 (mins)
Top 5 Timed Events
~~~~~~~~~~~~~~~~~~
% Total
Event Waits Time
(s) Call Time
-------------------------------------------- ------------ -----------
---------
CPU time 107
78.54
log file parallel write 705 12
9.13
buffer busy waits 12,485 12
8.52
latch: library cache 68
1 .70
LGWR wait for redo copy 3,794 1
.47
这就是ASSM的主要作用之一:不必手动地确定许多关键存储参数的正确设置。

10.2.5 PCTFREE和 PCTUSED

一 般而言,PCTFREE参数用来告诉Oracle应该在块上保留多少空间来完成将来的更新。默认情况下 , 这个值是10%。如果自由空间的百分比高于 PCTFREE中的指定值,这个块就认为是“自由的”。PCTUSED 则告诉Oracle当前不“自由”的一个块上自由空间百分比需要达到多大才能使它再 次变为自由的。默认 值是40%1。
如 前所述,对于一个表(而不是一个IOT,有关内容稍后再介绍),PCTFREE会告诉Oracle:块上 应该保留多大的空间来完成将来的更新。这说明,如 果我们使用的块大小为8KB,只要向块中增加一个新 行,就会导致块上的自由空间下降大约800字节,Oracle会使用FREELIST的另一个块,而不 是现有的块 。 块上这10%的数据空间会预留出来,以便更新该块上的行。
1. 实际上PCTUSED的含义是,如果块上不自由的空间到达或小于PCTUSED参数 指定的百分比时,这个块将重新变为自由,如倘若PCTUSED为40%,那么块上不自由的 空间小于40%时,即自由空间达到60%时,这个块就重新变为自由。——译者注。
注意 对 于不同的表类型,PCTFREE和PCTUSED的实现有所不同。对于某些表类型,这两个参数都要使用,而 另外一些表类型只使用PCTFREE,而且对于 这些表类型,仅当创建对象时才会使用PCTFREE。IOT在创建 时可以使用PCTFREE在表中预览空间来完成将来的更新,但是在其他方面并不使用 PCTFREE,例如,PCTFREE 不用于决定何时停止向一个给定块中插入行。
根 据你使用的是ASSM表空间还是MSSM表空间,这两个参数的实际作用会有所不同。使用MSSM时 , 这些参数设置控制着块何时放入freelist中,以 及何时从freelist中取出。如果使用默认值:PCTFREE 为10,PCTUSED为40,那么在块到达90%满之前(有10%以上的自由空间), 这个块会一直在freelist 上。一旦到底90%,就会从freelist中取出,而且直到块上的自由空间超过了块的60%时,才会重新回到 freelist上,在此之前,这个块一直不在freelist上。
使用ASSM时,PCTFREE仍然会限制能否将一个新行插入到一个块中,但是它不会控制一个块是否在
freelist上,因为ASSM根本不使用freelist。在ASSM中,PCTUSED将被忽略。
PCTFREE有3 种设置:太高、太低好刚好。如果把块的 PCTFREE设置得过高,就会浪费空间。如果把 PCTFREE设置为50%,而你从未更新数据,那么每个块都会浪 费50%的空间。不过,在另一个表上,50%可 能非常合理。如果行初始很小,现在想将行的大小加倍,但是倘若PCTFREE设置得太小,更新行时就会导 致 行迁移。

1. 行迁移

到底什么是行迁移?行迁移(row migration)是指由于某一行变得太大,无法再与其余的行一同放 在创建这一行的块中(块中已经放不下这一行),这就要求这一行离开原来的块。这一节将分析行迁移。 首先来看一个块,如同10-3所示。

图10-3更新前的数据块
这 个块上大约1/7是自由空间。不过,我们想通过一个 UPDATE将第4行所有的空间加倍(第4行现 在占用了块上1/7的空间)。在这种情况下,即使 Oracle合并了块上的空间(如同10-4所示),还是没 有足够的空间将第4 行的大小加倍,因为自由空间小于第4行的当前大小。

图10-4 合并自由空间之后可能得到的数据块
如 果这一行能在合并的空间中放下,自然就会这么做。不过,在此Oracle没有完成这个合并,块还 是保持原样。因为第4行如果还呆在这个块上,它就必须跨 块,所以Oracle会移动或迁移这一行。不过, Oracle不能简单地移动这一行,它必须留下一个“转发地址”。可能有一些索引物理地指向第4行的这个 地址。简单的更新不会同时修改这些索引(注意对于分区表则有一个特例:更新分区表时,rowid即行地 址会改变。这种情况将在第13章介绍)。因此, Oracle迁移这一行时,它会留下一个指针,指示这一行 实际上在什么位置。更新之后,块可能如图10-5所示。

图10-5 迁移行示意图
因 此,迁移行(migrated row)就是这一行从最初所插入的块上移到另外的某个块上。为什么这会 带来问题?你的应用绝对不会知道存在行迁移;你使用的SQL也没有任何不同。行迁移 只会影响性能。如 果你通过一个索引来读这一行,索引会指向原来的块,那个块再指向这个新块。要得到具体的行数据,一 般并不是执行两个左右的I/O就可以得 到行数据。单独来看,这不是大问题,甚至根本注意不到。不过, 如果这种行所占的比例相当大,而且有大量用户在访问这些行,你就会注意到这种副作用了。访问 这些数 据的速度开始变慢(额外的I/O以及与I/O相关的闩定都会增加访问时间),缓冲区缓存的效率开始下降
(需要缓存两个块,而如果行没有迁移就只需要 缓存一个块),另外表的大小好复杂性都有所增加。由于 这些原因,你可能不希望迁移行。
有 意思的是,如果一行从左边的块迁移到右边的块,如同10-5所示,而且它在将来某个时间点还要 再迁移,Oracle会这样做呢?造成这种又一次迁移的原因 可能是:在这一行迁移到的“目标”块上又增 加了其他的行,然后这一行再次更新,变得更大。Oracle实际上会把这一行迁移回原来的块,如果有足够
的空 间,仍放回原地(这么一来,这一行可能变得“未迁移”)。如果没有足够的空间,Oracle会把这 一行迁移到另外的某个块上,并修改原来块上的转发地址。 因此,行迁移总是涉及一层间接性。
所以,现在我们再回到PCTFREE,来说明这个参数的作用:如果设置得当,这个参数可以帮助你尽量 减少行串链。

2. 设置PCTFREE和 PCTUSED值

设 置PCTFREE和PCTUSED是一个很重要的主题,不过往往被忽视。总的来说,使用MSSM时,PCTUSED 和PCTFREE都很重要;对于 ASSM,只有PCTFREE是重要的。一方面,你要使用这些参数来避免迁移过多的 行。另一方面,要使用这些参数避免浪费太多的空间。你需要查看对象,描 述这些对象要如何使用,然后 为设置这些值得出一个逻辑计划。设置这些参数时,如果主观地采用一般经验很可能招致失败;必须根据 具体的使用设置。可以考虑以 下做法(要记住,这里的“高”和“低”都是相对的;而且使用ASSM时仅 PCTFREE适用):
q 高PCTFREE,低PCTUSED:如果你插入了将要更新的大量数据,而且这些更新会频繁地增 加行的大小,此时就适合采用这种设置。这种设置在插入后会在块上预留大量的空间(高 PCTFREE),并使得将块放回到freelist之前必须几乎为空(低PCTUSED)。
q 低PCTFREE,高PCTUSED:如果你只想对表完成INSERT或DELETE,或者如果你确实要完成 UPDATE,但UPDATE只是缩小行的大小,此时这种设置就很适合。

10.2.6 LOGGING和 NOLOGGING

通 常对象都采用LOGGING方式创建,这说明对象上完成的操作只要能生成redo就都会生成redo。 NOLOGGING则允许该对象完成某些操作时可以 不生成redo;这个内容在上一章详细介绍过。NOLOGGING只 影响几个特定的操作,如对象的初始创建,或使用SQL*Loader的直接路径加载,或者重建(请参考Oracle SQL Reference手册来了解你使用的数据库对象可以应用哪些操作)。
这个选项并不会完全禁用对象的重做日志生成,只是几个特定的操作不生成日志而已。例如,如果把 一个表创建为SELECT NOLOGGING,然后INSERT INTO THAT_TABLE VALUES(1),这个INSERT就会生成日志, 但是表创建可能不生成redo(DBA可以在数据库或表空间级强制生成日志)。

10.2.7 INITRANS和 MAXTRANS

段 中每个块都有一个块首部。这个块首部中有一个事务表。事务表中会建立一些条目来描述哪些事 务将块上的哪些行/元素锁定。这个事务表的初始大小由对象的 INITRANS设置指定。对于表,这个值默认 为2(索引的INITRANS也默认为2)。事务表会根据需要动态扩展,最大达到MAXTRANS个条目 (假设块 上有足够的自由空间)。所分配的每个事务条目需要占用块首部中的23~24字节的存储空间。注意,对于 Oracle 10g,MAXTRANS则会忽略,所有段的MAXTRANS都是255。