对象的空间管理
这个名字是照着书上取的,其实有些歧义。这一篇其实学习的是Oracle对象的存储空间属性设置,不过还是尊重书上的吧。这一块东西说重要也重要,说不重要也不重要。你不去管它完全都照着Oracle的默认设置,应该也影响不了多少性能,但是对于大数据量的数据库,就需要考虑这方面的性能问题了,所以这也算是DBA必须掌握的只是之一,看一下:
一、管理数据块空间
数据块的大小是在创建的时候就已经指定的,所以可以进行修改的是数据块的PCTFREE、PCTUSED参数。
可以进行以下的操作:
* 改善写入检索数据时的性能
* 减少数据块中未使用空间的数量
* 减少数据块之间行链接的数量
1、指定PCTFREE参数
PCTFREE参数用于设置为数据块中需要保留的空闲百分比。例如:
PCTFREE的默认值是10,可以设置0-99之间的任意数值,只需满足 PCTFREE + PCTUSED <= 100 即可
PCTFREE的参数值设置可以满足以下条件:
① PCTFREE设置较小的作用:
* 为盘区表中现有行的更新保留较少的空间
* 允许通过插入来更完整得填充数据块
* 可以节省空间,因为表或索引的所遇数据存储在较少数据库块中
② PCTFREE设置较大的作用:
* 为表中现有行的将来更新保留更多的空间
* 为同样数量的插入数据申请更多的数据块(每个数据块利用较少)
* 提高更新性能(无需频繁链接行片)
③ 非簇表的PCTFREE参数
非簇表行中的数据可能会随时间推移增大则需要多留一些PCTFREE
④ 簇表的PCTFREE参数
除了依照非簇表的规则外,达到PCTFREE百分比时,同一簇码的任何一个表新行进入新块时均会被链接到现有的簇码
⑤ 索引的PCTFREE参数
只能在初始创建索引时才能指定索引的PCTFREE值
2、指定PCTUSED参数
设置PCTUSED参数,当一个数据块填满到PCTFREE设置的百分比时,只有在所用空间下降到PTCUSED参数值以下时才继续为该数据块插入新行。
例如:
PCTUSED的默认值是40,同样可以设置为0-99之间的任意数值。
PCTUSED的参数值设置可以满足以下条件:
① PCTUSED设置较小的作用:
* 降到PCTUSED以下时,减少在UPDATE和DELETE语句中因数据块移动到自由列表引起的处理开销
* 增加数据库中的未用空间
② PCTUSED设置较大的作用:
* 提高空间利用率
* INSERT和UPDATE语句中增加处理开销
3、选择PCTUSED和PCTFREE的参数值
在设置PCTUSED和PCTFREE参数时,需要注意以下几点:
* PCTFREE和PCTUSED参数之和必须等于或小于100
* 若两者和为100,则Oracle只保持PCTFREE参数指定的空闲空间,且处理开销是最大的
* 两者之和与100的差值越小,说明空间利用率越高
下面举例说明:
① PCTFREE=20 PCTUSED=40
环境:包括增大行大小的UPDATE语句的普通动作。
说明:PCTFREE设置为20为UPDATE提供足够的空间,PCTUSED设置为40以便更新时少做处理,提高性能。
② PCTFREE=5 PCTUSED=60
环境:包含INSERT和DELETE语句,以及不增大行大小的UPDATE。
说明:不增大行大小所以PCTFREE比较小,而PCTUSED设为60以便时使DELETE之后的空间马上可以使用,且减少处理开销。
③ PCTFREE=5 PCTUSED=40
环境:表非常大且存储是首要考虑,包含只读事务的动作。
说明:因为是大表,所以设置PCTFREE为5,完全填充每个数据块。
4、指定事务入口(INITRANS、MAXTRANS)
INITRANS参数用于指定DML事务入口的数目,即为事务入口保留空间。
MAXTRANS参数用于限制一个数据块中同时使用数据的事务入口数目。
INITRANS和MAXTRANS参数的设置需要考虑一下因素:
* 为事务入口保留的空间与为数据库数据保留的空间相比较
* 任何时候可能访问同一数据块的并发事务的数目
例如:
① 一个表非常大,并且只有少数的用户同时访问该表,多个并发事务访问一个数据块的机会就比较小,因此INITRANS可以设置得小一点,特别是如果数据库中的空间非常宝贵的情况下。
② 一个表通常被很多用户同时访问,这时需要INITRANS设置得较大一些来与分配事务的入口,这样就省去了必须分配事务入口空间的开销。同事设置一个较大的MAXTRANS参数值,以便没有用户为访问必要数据块而造成的等待。
二、设置存储参数
1、确定存储参数
首先来看一个设定存储参数的例子:
CREATE TABLE players
(code number(10) primary key,
lastname VARCHAR2(20),
firstname VARCHAR2(15),
position VARCHAR2(20),
team VARCHAR2(20))
PCTFREE 10
PCTUSED 40
STORAGE
(INITIAL 25K
NEXT 10K
MAXEXTENTS 10
MINEXTENS 3);
说明:
① INITIAL:创建段时分配的第一个盘区大小。默认为5个数据块,最小值2个数据块(字典管理表空间)或3个数据块(本地管理表空间),最大值由操作系统指定。注意该参数不能在ALTER语句中指定。
② NEXT:分配给下一个增加的盘区大小。第二个盘区为NEXT值,再往后NEXT设置为上一个NEXT*(1+PCTINCREASE/100)。该参数默认值为5个数据块,最小值为1个数据块,最大值由操作系统指定。
③ PCTINCREASE:用于计算NEXT的值,NEXT*(1+PCTINCREASE/100)。默认值为50(%),最小值为0(%),最大值由操作系统指定。
④ MINEXTENTS:创建段时分配的盘区总数。允许创建时分配一个大的空间,即使连续空间不够用。默认值为1(盘区),回滚段为2(盘区),默认值即最小值,最大值没有限制。
⑤ MAXEXTENTS:能够分配给段的最大盘区总数(包括第一个),默认值取决于数据块大小和操作系统。最小值为MINEXTENTS的最小值,最大值没有限制。
⑥ FREELIST GROUPS:数据库对象的空闲表组数。RAC中的实例数将每个实例映射到一个空闲组中。默认值/最小值为1,最大值为RAC的实例数。
⑦ FREELISTS:模式对象的每个空闲表组中空闲表的数目,对表空间无效,默认值/最小值为1,最大值取决于数据块的大小。
⑧ OPTIMAL:只与回滚段有关。
⑨ BUFFER_POOL:为模式对象定义一个默认的缓冲池,对表空间或回滚段无效。
2、需要设置存储参数的对象
① 表空间中的段
在创建表空间时使用STORAGE子句进行设置
当表空间层指定MINEXTENTS参数时,该表空间中分配的任何盘区舍入到一个最小盘区的倍数
② 数据段
在使用表、物化视图、物化视图日志的CREATE或ALTER语句中的STORAGE子句,可以为非簇表、物化视图、物化视图日志数据段配置存储参数。
使用CREATE CLUSTER或ALTER CLUSTER语句中的STORAGE子句,为簇的数据段设置存储参数,而不是继承自表或物化视图。
分区表的存储参数继承自表,若表上没有指定,则继承自表空间。
③ 索引段
用CREATE INDEX或ALTER INDEX语句中的STORAGE子句设置
④ LOB、VARRAY、嵌套表
3、修改存储参数值
可以修改表空间的默认存储参数和单个段的特定存储参数。也可以为表空间重置默认参数。
注:修改后只影响新创建的对象,或者为段新分配的盘区。
不能为现有的表、簇、索引、回滚段修改INITIAL、MINEXTENTS参数。
如果一个段的NEXT参数修改,则下次增加盘区就是新的NEXT,随后按以前方式增长。
如果一个短的NEXT和PCTINCREASE都被修改,则下一个盘区就是新的NEXT,随后也以新参数增长。
4、了解存储参数生效先后次序
对象的层次越低,存储参数的有效性就越高:
① ALTER [TABLE|CLUSTER|MATERIALIZED VIEW|MATERILIZED VEW LOG|INDEX|ROLLBACK] SEGMENT
② CREATE [TABLE|CLUSTER|MATERIALIZED VIEW|MATERILIZED VEW LOG|INDEX|ROLLBACK] SEGMENT
③ ALTER TABLESPACE
④ CREATE TABLESPACE
⑤ Oracle默认值
注:临时段的存储参数一般都使用相关的表空间设置的默认存储参数
5、存储参数对空间分配的影响
举例如下:
... ...
STORAGE
(INITIAL 100K
NEXT 100K
MINEXTENTS 2
MAXEXTENTS 5
PXTINCREASE 50)
若DB_BLOCK_SIZE为2K,则其盘区的增长情况如下:
盘区号 盘区大小 NEXT取值
------ ------------------- -----------------
1 50个块或102400字节 50个块或102400字节
2 50个块或102400字节 75个块或153600字节
3 75个块或153600字节 113个块或231424字节
4 115个块或235520字节 170个块或348160字节
5 170个块或348160字节 无NEXT,因为MAXEXTENTS=5
三、回收空间
在为段分配了空间之后,如果发现有未使用或过多分配的空间,可以将其释放以便使用未时空的空间来被其他段使用。
1、观察高水位标记
使用DBMS_SPACE.UNUSED_SPACE函数查看一个段中未使用空间的数量。
注:低于高水位标记的空间不能被释放,即使空间中没有数据。
但是如果段是空的,可以使用TRUNCATE ... DROP STORAGE语句释放空间
2、发布空间回收语句
ALTER TABLE table DEALLACATE UNUSED KEEP integer;
ALTER INDEX index DEALLOCATE UNUSED KEEP integer;
ALTER CLUSTER cluster DEALLOCATE UNUSED KEEP integer;
其中KEEP子句是可选的,指定保留不被收回的未使用空间。如果剩下的盘区个数变得比MINEXTENTS参数值小,那么MINEXTENTS就会改变以反应新的个数。如果初始盘区变小,将修改INITIAL参数值以反应初始盘区的新大小。
若没有指定KEEP子句,则所有高于高水位标记的未使用空间均被回收。MINEXTENTS和初始盘区大小不变。
3、回收空间的例子
① 一个表由3个盘区组成,第一个10K,第二个20K,第三个30K。高水位标记在第二个盘区的中部,且有40K的未使用空间,
则使用ALTER TABLE dquon DEALLOCATE UNUSED;语句后的改变如下:
所有未使用空间被回收,表dquon只剩下两个盘区,且第二个盘区变成10K。
如果是使用ALTER TABLE dquon DEALLOCATE UNUSED KEEP 10K;语句,则:
盘区3被全部收回,但盘区2保持20K不变
② 在①的表盘区3被回收,且盘区2缩减为10K之后,下一个分配的盘区讲仍然是30K,而这是我们不希望的。
所以可以手动指定一下下一个盘区的大小:
ALTER TABLE dquon STORAGE (NEXT 20K);
③ 如果表dquon有一个参数MINEXTENTS为2,则①中的两次操作都将没有变化。
但是如果MINEXTENTS=3,则在①中的第一个例子中,语句将没有效果。而第二个例子中,会产生同样效果,但MINEXTENTS修改为2。