ITPub博客

首页 > 数据库 > Oracle > 【表压缩】使用表压缩技术将表所占用空间降低到最小

【表压缩】使用表压缩技术将表所占用空间降低到最小

原创 Oracle 作者:OCMU联盟 时间:2009-12-06 22:29:45 0 删除 编辑
很多情况下,Oracle默认的表存储策略并不符合我们使用数据的实际情况。例如,在OLAP类型的系统中,数据的使用方式一般是定期批量初始化大量数据,此后的工作便是查询、分析和统计,很少的修改动作。基于这样的使用前提,我们完全有理由将表的使用空间尽量减少,以便节省存储空间并提高系统的吞吐量。

哪些技术可以降低表的存储空间呢?
第一种方法是降低PCTFREE的值,因为我们没有必要为以后的更新留有空间,极端情况下我们也可以将PCTFREE的值设置为0;
第二种方法是表压缩技术,使用这种技术可以进一步减少表所占用的空间。

通过实验我们来展示一下这两种方法,重点会放在使用表压缩技术带给我们的神奇效果。

1.在系统默认的存储参数下创建表T,该表是借助ALL_OBJECTS视图内容生成的,包含一千万条记录,共占用段空间1G。
1)确认记录条数:一千万条。
sec@ora10g> select count(*) from t;

  COUNT(*)
----------
  10000000

2)使用DBMS_METADATA.GET_DDL得到T表的全貌,可见默认的PCTFREE值是10。
sec@ora10g> set longchunksize 150
sec@ora10g> select dbms_metadata.get_ddl('TABLE','T','SEC') from dual;

DBMS_METADATA.GET_DDL('TABLE','T','SEC')
-----------------------------------------------------------------------

  CREATE TABLE "SEC"."T"
   (    "X" NUMBER,
        "OWNER" VARCHAR2(30) NOT NULL ENABLE,
        "OBJECT_NAME" VARCHAR2(30) NOT NULL ENABLE,
        "SUBOBJECT_NAME" VARCHAR2(30),
        "OBJECT_ID" NUMBER NOT NULL ENABLE,
        "DATA_OBJECT_ID" NUMBER,
        "OBJECT_TYPE" VARCHAR2(19),
        "CREATED" DATE NOT NULL ENABLE,
        "LAST_DDL_TIME" DATE NOT NULL ENABLE,
        "TIMESTAMP" VARCHAR2(19),
        "STATUS" VARCHAR2(7),
        "TEMPORARY" VARCHAR2(1),
        "GENERATED" VARCHAR2(1),
        "SECONDARY" VARCHAR2(1)
   ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS NOLOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
  TABLESPACE "TBS_SEC_D"

3)确认表T占用的段空间大小,我们的目标就是在此基础上使其占用的段空间大小尽量的小。
sec@ora10g> select owner,segment_name table_name,segment_type type,bytes/1024/1024 mb from dba_segments where segment_name = 'T';

OWNER     TABLE_NAME     TYPE                         MB
--------- -------------- -------------------- ----------
SEC       T              TABLE                      1088

2.减少存储空间的第一次尝试:将PCTFREE的值降为0。
1)为对比方便,我们使用CTAS方法创建表T_PCTFREE0
sec@ora10g> create table t_pctfree0 pctfree 0 as select * from t;

Table created.

2)查看一下空间的节省情况,大约节省了原T表所占空间的10%。
sec@ora10g> select owner,segment_name table_name,segment_type type,bytes/1024/1024 mb from dba_segments where segment_name = 'T_PCTFREE0';

OWNER     TABLE_NAME     TYPE                         MB
--------- -------------- -------------------- ----------
SEC       T_PCTFREE0     TABLE                       960

3.减少存储空间的第二次尝试:使用表压缩技术。
1)使用“compress”选项创建具有表压缩特性的表T_COMPRESS
sec@ora10g> create table t_compress compress as select * from t;

Table created.

2)查看一下空间的节省情况,此时大约节省了原T表所占空间的65%,效果惊人。
sec@ora10g> select owner,segment_name table_name,segment_type type,bytes/1024/1024 mb from dba_segments where segment_name = 'T_COMPRESS';

OWNER     TABLE_NAME     TYPE                         MB
--------- -------------- -------------------- ----------
SEC       T_COMPRESS     TABLE                       376

3)使用表压缩技术创建的表本身就具有PCTFREE为“0”的性质。
sec@ora10g> select dbms_metadata.get_ddl('TABLE','T_COMPRESS','SEC') from dual;

DBMS_METADATA.GET_DDL('TABLE','T_COMPRESS','SEC')
----------------------------------------------------------------------

  CREATE TABLE "SEC"."T_COMPRESS"
   (    "X" NUMBER,
        "OWNER" VARCHAR2(30) NOT NULL ENABLE,
        "OBJECT_NAME" VARCHAR2(30) NOT NULL ENABLE,
        "SUBOBJECT_NAME" VARCHAR2(30),
        "OBJECT_ID" NUMBER NOT NULL ENABLE,
        "DATA_OBJECT_ID" NUMBER,
        "OBJECT_TYPE" VARCHAR2(19),
        "CREATED" DATE NOT NULL ENABLE,
        "LAST_DDL_TIME" DATE NOT NULL ENABLE,
        "TIMESTAMP" VARCHAR2(19),
        "STATUS" VARCHAR2(7),
        "TEMPORARY" VARCHAR2(1),
        "GENERATED" VARCHAR2(1),
        "SECONDARY" VARCHAR2(1)
   ) PCTFREE 0 PCTUSED 40 INITRANS 1 MAXTRANS 255 COMPRESS LOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
  TABLESPACE "TBS_SEC_D"

4.减少存储空间的第三次尝试:“使用表压缩技术” + “选取最佳排序字段”。
表压缩技术从原理上讲,是通过将数据块中重复数据抽取成为符号表的方法来实现的,因此,如果我们有办法将存储在每一块上存储的重复数据尽量多,便可以进一步的减少表所占用空间大小。我们可以使用order by对原表中重复度较大的字段进行排序的方法达到这个目的。
1)针对表T我们知道,在owner, object_type, object_name字段上存在大量的重复信息,因此我们对其进行排序后再创建压缩表T_COMPRESS_ORDER。
sec@ora10g> create table t_compress_order compress as select * from t order by owner, object_type, object_name;

Table created.

2)查看一下空间的节省情况,此时大约节省了原T表所占空间的88%,原1G的表现在仅为136M,真是叹为观止!
sec@ora10g> select owner,segment_name table_name,segment_type type,bytes/1024/1024 mb from dba_segments where segment_name = 'T_COMPRESS_ORDER';

OWNER     TABLE_NAME       TYPE                         MB
--------- ---------------- -------------------- ----------
SEC       T_COMPRESS_ORDER TABLE                       136

5.一味的减少表的存储空间是不可取的
有利必有弊,虽然我们上面通过对“owner, object_type, object_name”三个字段排序后得到了一个非常好的压缩效果。不过在某些检索条件下该表并没有优势,例如我们使用非排序字段作为where子句中的条件进行查询时,查询效率会大打折扣。

6.表压缩技术适用场合
如果是OLTP系统,这个技术是非常不合适的,原因不言自明(PCTFREE是0;OLTP增删改查活动频繁);
非常适合以查询为主(或只读)的静态数据表;
多见于数据仓库系统。

7.小结
表压缩技术在降低表的存储空间方面功不可没。降低了表的存储空间一方面可以节省大量宝贵的存储资源,同时也可以提升系统的整体性能(需读取的数据块数大大减少)。不过表压缩技术本身具有的限制亦不容忽视,使用前需要做好充分的测试。

Good luck.

secooler
09.12.06

-- The End --

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70034820/viewspace-2994021/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
OCM联盟( Oracle Certified Master Union)是由侯圣文(ACE总监)发起的一个公益组织,旨在为每一个OCM大师提供一个可以继续展示自己才华,技术和实力的平台。

注册时间:2007-05-27

  • 博文量
    799
  • 访问量
    8406979