在Oracle Database 11g之前,当创建一个实体对象时,如创建一个数据表,数据库即为该对象创建段(Segment),并随之分配一定数量的区间(Extent),这一状况在11g中发生了改变,延迟段空间创建(Deferred Segment Creation)技术被引入到数据库中,这个特性的功能是:当创建一个对象时(11.2.0.2之前不支持分区对象),数据结构定义被存储,但是并不立即创建数据段,直到有第一行记录插入时才动态创建分配段空间。
这个特性的一个优点是可以快速初始化数据库并降低空间开销,很多数据库系统初始化时会批量创建大量的数据表,如果不分配空间则可以大幅度提高初始化速度,而在有些系统中,可能很多数据表永远都不会存储数据,那么这个特性使得最基本的空间分配都不需要了。
初始化参数deferred_segment_creation用于控制该特性,设置为False可以关闭这个功能:
Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - Production With the Partitioning, OLAP, Data Mining and Real Application Testing options SQL> show parameter deferred_segment_creation NAME TYPE VALUE ------------------------------------ ----------- ---------------------------- deferred_segment_creation boolean TRUE
除了这个参数之外,在建表时也可以通过指定SEGMENT参数来定义是IMMEDIATE还是DEFERRED方式来创建数据段:
以下通过测试来简要说明一下这个新的特性。
SQL> create user eyglee identified by eyglee; SQL> grant connect,resource,dba to eyglee; SQL> connect eyglee/eyglee Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 Connected as eyglee SQL> create table dsc as select * from dba_tables where 1=0; Table created
注意此时创建的对象未创建数据段:
SQL> select segment_name,bytes from user_segments; SEGMENT_NAME BYTES -------------------------------------------------------------------------------- ---------- Executed in 1.201 seconds
插入一条记录之后,空间分配:
SQL> insert into dsc select * from dba_tables where rownum <2; 1 row inserted SQL> select segment_name,bytes from user_segments; SEGMENT_NAME BYTES -------------------------------------------------------------------------------- ---------- DSC 65536
11.2.0.2中,TRUNCATE命令得到了增强, TRUNCATE TABLE中的"DROP ALL STORAGE" 选项可以彻底删除SEGMENTS,来比较一下TRUNCATE语句的不同选项:
SQL> truncate table dsc drop storage; Table truncated SQL> select segment_name,bytes from user_segments; SEGMENT_NAME BYTES -------------------------------------------------------------------------------- ---------- DSC 65536 SQL> col segment_name for a40 SQL> truncate table dsc drop all storage; Table truncated SQL> select segment_name,bytes from user_segments; SEGMENT_NAME BYTES ---------------------------------------- ---------- Executed in 0.187 seconds
对于未分配空间的对象,新增加的特性还包括通过DBMS_SPACE_ADMIN.MATERIALIZ E_ DEFERRED_SEGMENTS实体化延迟段对象:
SQL> exec DBMS_SPACE_ADMIN.MATERIALIZE_DEFERRED_SEGMENTS('EYGLEE','DSC'); PL/SQL procedure successfully completed SQL> select segment_name,bytes from user_segments; SEGMENT_NAME BYTES ---------------------------------------- ---------- DSC 65536
对于从11.2.0.2之前版本升级的系统,如果有空表,可以通过DBMS_SPACE_ADMIN.DROP_EMPTY_SEGMENTS 过程清除这些SEGMENTS.
延迟段空间创建特性自11.2.0.2开始支持分区表,并且对于分区表,新分配的segments创建时缺省的extent size为8M,而不再是以前的64K:
SQL> create table dscp ( 2 id number, 3 name varchar2(20)) 4 partition by hash (name) partitions 8; Table created. SQL> select segment_name,bytes from user_segments; no rows selected SQL> exec DBMS_SPACE_ADMIN.MATERIALIZE_DEFERRED_SEGMENTS('EYGLEE','DSCP'); PL/SQL procedure successfully completed. SQL> select segment_name,bytes from user_segments; SEGMENT_NAME BYTES ---------------------------------------- ---------- DSCP 8388608 DSCP 8388608 DSCP 8388608 DSCP 8388608 DSCP 8388608 DSCP 8388608 DSCP 8388608 DSCP 8388608
在Oracle Database 11gR1中,exp工具将无法导出这些使用延迟创建方式创建的数据表,这是因为exp工具存在BUG,使用expdp不存在这个问题,并且该问题在11gR2中被修正:
exp file=tab.dmp tables=dsc userid=eygle/eygle About to export specified tables via Conventional Path … EXP-00011: EYGLE.DSC does not exist Export terminated successfully with warnings.
这是段空间管理上,Oracle的又一个小小增强。