很多情况下,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/
,如需转载,请注明出处,否则将追究法律责任。