Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2895962
  • 博文数量: 599
  • 博客积分: 16398
  • 博客等级: 上将
  • 技术积分: 6875
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-30 12:04
个人简介

WINDOWS下的程序员出身,偶尔也写一些linux平台下小程序, 后转行数据库行业,专注于ORACLE和DB2的运维和优化。 同时也是ios移动开发者。欢迎志同道合的朋友一起研究技术。 数据库技术交流群:58308065,23618606

文章分类

全部博文(599)

文章存档

2014年(12)

2013年(56)

2012年(199)

2011年(105)

2010年(128)

2009年(99)

分类: Oracle

2013-01-31 14:27:32

最近客户的表由于插入太频繁,导致空间分配的次数比较多,客户想通过设置表的存储参数
NEXT 为一个较大的值,来尽量减少空间分配的频率。

由于目前的数据库都是采用的LMT类型的表空间,这些参数基本不起作用了,设置他们仅仅在初始化段的时候
来计算段的初始大小。

 

MOS有段话如下:

In locally managed tablespaces, Oracle uses object's storage parameters INITIAL,
NEXT, PCTINCREASE, and MINEXTENTS in conjunction with the size of extents
specified for the tablespace to determine the object's first extent.
For example, in a uniform locally managed tablespace with 2M extents, if you
specify (in CREATE TABLE, etc. )INITIAL value of 1M, NEXT 2M, and MINEXTENTS 4,
then Oracle initially creates four 2M extents - to provide for 1M+2M+2M+2M=7M
of initial size of the object.

下面我们来测试一下:


SQL>  SELECT TABLESPACE_NAME,ALLOCATION_TYPE,SEGMENT_SPACE_MANAGEMENT
  2  FROM DBA_TABLESPACES
  3   WHERE TABLESPACE_NAME='DATA';

TABLESPACE_NAME      ALLOCATIO SEGMEN
-------------------- --------- ------
DATA                 SYSTEM    AUTO

SQL> CREATE TABLE T TABLESPACE DATA
  2  STORAGE(INITIAL 10M NEXT 33M MINEXTENTS 5 MAXEXTENTS 20)
  3  AS SELECT * FROM ALL_OBJECTS WHERE 1=0;

表已创建。

SQL> SELECT BYTES/1024/1024 FROM USER_SEGMENTS WHERE SEGMENT_NAME='T';

BYTES/1024/1024
---------------
            142

SQL> SELECT 10+33*4 FROM DUAL; <--10M+33M*4

   10+33*4
----------
       142
      
      
可以看到ORACLE通过存储参数来计算初始段的大小。
      

SQL> SELECT BYTES/1024/1024 FROM USER_SEGMENTS WHERE SEGMENT_NAME='T';

BYTES/1024/1024
---------------
            142
 
SQL> CREATE TABLE A AS SELECT * FROM ALL_OBJECTS;

表已创建。


SQL> SELECT BYTES/1024/1024 FROM USER_SEGMENTS WHERE SEGMENT_NAME='A';

BYTES/1024/1024
---------------
              6
 
多次执行
INSERT /*+APPEND*/ INTO A SELECT * FROM ALL_OBJECTS 并提交。


 
                      
 目前A表的大小为43M         
SQL> SELECT BYTES/1024/1024 FROM USER_SEGMENTS WHERE SEGMENT_NAME='A';

BYTES/1024/1024
---------------
             43

SQL> SELECT 43*3 FROM DUAL;

      43*3
----------
       129

 

SQL> INSERT /*+APPEND*/ INTO T SELECT * FROM A;

已创建399416行。

SQL> COMMIT;

提交完成。

SQL> INSERT /*+APPEND*/ INTO T SELECT * FROM A;

已创建399416行。

SQL> COMMIT;

提交完成。

SQL> INSERT /*+APPEND*/ INTO T SELECT * FROM A;

已创建399416行。

SQL> COMMIT;

提交完成。

SQL> SELECT BYTES/1024/1024 FROM USER_SEGMENTS WHERE SEGMENT_NAME='T';

BYTES/1024/1024
---------------
            142

SQL> INSERT /*+APPEND*/ INTO T SELECT * FROM ALL_OBJECTS;

已创建49927行。

SQL> COMMIT;

提交完成。

SQL> INSERT /*+APPEND*/ INTO T SELECT * FROM ALL_OBJECTS;

已创建49927行。

SQL> COMMIT;

提交完成。

SQL> SELECT BYTES/1024/1024 FROM USER_SEGMENTS WHERE SEGMENT_NAME='T';

BYTES/1024/1024
---------------
            142

SQL> INSERT /*+APPEND*/ INTO T SELECT * FROM ALL_OBJECTS; <--这次将会导致表分配新的空间。

已创建49927行。

SQL> COMMIT;

提交完成。

SQL> SELECT BYTES/1024/1024 FROM USER_SEGMENTS WHERE SEGMENT_NAME='T';

BYTES/1024/1024
---------------
            150


可以看到ORACLE仅仅分配了8M的EXTENT,并不是存储参数NEXT设置的33M。

同时EXTENTS数也可能超出MAXEXTENTS设置的值。

SQL> insert /*+append*/ into t select * from t;

已创建1348030行。

SQL> COMMIT;

提交完成。

SQL> select count(1) from user_extents where segment_name='T';

  COUNT(1)
----------
        38
       
如果要控制每次分配的区的大小,可以再创建表空间的时候指定UNIFORM SIZE 33M。       

阅读(1623) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~