对象的空间管理
				
		
		
				
				 
		
				
						    这个名字是照着书上取的,其实有些歧义。这一篇其实学习的是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。