ORACLE的数据段压缩技术 part1

1引言

做为DBA空间的紧张是常遇到的一个问题,有时一个大的表就会占用几十GB及至上百GB的空间。存储历史数据的表常常都是这样,特别是数据仓库型应用(如经营分析应用)数据库这样的问题就更加突出。如今,在计算机技术中数据压缩技术已经十分广泛和成熟了。在windows系统中有winrarwinzip,7-zip等等这样的软件,UNIX操作系统中相应的也有compressgzip这样的压缩命令及软件。这些压缩工具的使用使我们节约了很多的空间,在ORACLE 9i之前的版本我有时在想,ORACLE什么时侯也有类似的功能可以节约空间,提高单位空间的使用价值。期待之余,ORACLE9i开始羞羞答答的引入表级压缩;10g在部分压缩功能略有增强,例如DataPump源数据的压缩、Rman备份的压缩等,并无本质的改观;Oracle11g才名正言顺的推出Advance Compression组件,支持全方面的压缩,ORACLE的白皮书说,11g采用了更先进的ZLIB要所算法,可以比Oracle10g的压缩算法快上40%,空间需求也将减少20%,压缩率可以达到74.67%。本文将立足于ORACLE9/10g这样的实际应用最多的版本探讨一下ORACLE的压缩技术,并简单介绍一下ORACLE11g的压缩方面的新特征。

[@more@]

2数据压缩实现原理

2.1原理简单描述

ORACLE的数据段压缩技术可以理解为“数据块”级压缩技术,也就是说是针对Block级别的数据压缩。它是在Block中引入symbol表,将Block中的重复数据在symbol中用一个项(指针)表示,即块中相同的ROW只存储一条,从而节约了空间。

2.2压缩数据块的存储结构

2.2.1建一行包含28672行数据的表T_ 28672

SQL> show user

USER is "SCOTT"

SQL>

SQL> select count(*) from t_28672;

COUNT(*)

----------

28672

2.2.2T_ 28672压缩前与压缩后段统计

压缩前:

SQL> select owner,segment_name,file_id,block_id,blocks

2 from dba_extents

3 where wner='SCOTT'

4 and segment_name='T_28672'

5 order by block_id

6 /

OWNER SEGMENT_NAME FILE_ID BLOCK_ID BLOCKS

----- -------------------- ---------- ---------- ----------

SCOTT T_28672 4 3729 8

SCOTT T_28672 4 3737 8

SCOTT T_28672 4 3745 8

SCOTT T_28672 4 3753 8

SCOTT T_28672 4 3761 8

SCOTT T_28672 4 3769 8

SCOTT T_28672 4 3777 8

SCOTT T_28672 4 3785 8

SCOTT T_28672 4 3793 8

SCOTT T_28672 4 3801 8

SCOTT T_28672 4 3809 8

SCOTT T_28672 4 3817 8

SCOTT T_28672 4 3825 8

SCOTT T_28672 4 3833 8

SCOTT T_28672 4 3841 8

SCOTT T_28672 4 3849 8

SCOTT T_28672 4 3977 128

17 rows selected.

SQL>

执行表压缩:

SQL> alter table T_28672 move COMPRESS;

Table altered.

压缩后:

SQL> select owner,segment_name,file_id,block_id,blocks

2 from dba_extents

3 where wner='SCOTT'

4 and segment_name='T_28672'

5 order by block_id

6 /

OWNER SEGMENT_NAME FILE_ID BLOCK_ID BLOCKS

----- -------------------- ---------- ---------- ----------

SCOTT T_28672 4 3857 8

SCOTT T_28672 4 3865 8

SCOTT T_28672 4 3873 8

SCOTT T_28672 4 3881 8

SCOTT T_28672 4 3889 8

SCOTT T_28672 4 3897 8

6 rows selected.

SQL>

简单总结:

从压缩前后段的数量上看,压缩还是相当节约空间的,17个区压缩成6个区,2倍的压缩比。

2.2.3dumpfile 4 block 3860

SQL> alter system dump datafile 4 block 3860;

System altered.

2.2.4结构分析

需要说明的是,如下的内容为完整.trc的节选,有关于block dump内容更详细的解释可以参照“DSI402e Data Types and Block Structures”,本文只观注与压缩有关的部分。

2.2.4.1 data header部分

此部分是总结的部分记录了块中有多少行的数据列存储的顺序记录表中记录的条数及重复记录的条数等信息。

data_block_dump,data header at 0x1103ff07c

===============

tsiz: 0x1f80

hsiz: 0x5b0

pbl: 0x1103ff07c

bdba: 0x01000f14

76543210

flag=-0------ *flag0表示是压缩块

ntab=2 *ntab表述数据块中表的数量,普通表的数据块种这个值应该是1

而压缩表大于1

nrow=700 *nrow表示该数据块中的记录数,此项表明该块中含700条记录

frre=-1

fsbo=0x5b0

fseo=0x106a

avsp=0x2a

tosp=0x2a

r0_9ir2=0x0 *9ir2表示的是这项压缩功能起始的版本

mec_kdbh9ir2=0xe

76543210

shcf_kdbh9ir2=----------

76543210

flag_9ir2=--R---OC

fcls_9ir2[9]={ 0 32768 32768 32768 32768 32768 32768 32768 32768 }

perm_9ir2[8]={ 6 7 2 3 5 4 1 0 }*表示实际存储字段顺序也就是说后面物理存储的顺序COL6,COL7,COL2...

0x30:pti[0] nrow=24offs=0 *记号表中有24条记录

0x34:pti[1] nrow=676 offs=24 *重复的记录有676

0x38:pri[0] offs=0x1f14

... ...

... ...

0x5ac:pri[698] offs=0x106f

0x5ae:pri[699]offs=0x106a

2.2.4.2记号表中的各条记录

24行的数据,部分数据省略掉

block_row_dump:

tab 0, row 0, @0x1f14

tl: 31 fb: --H-FL-- lb: 0x0 cc: 8*fb->flag byte H->header F->first L->last

*cc->column count(列数量)

col 0: [ 2] c1 15 *列长度为2,类型为c115

col 1: *NULL*

col 2: [ 5] 434c45 52 4b

col 3: [ 3] c2 50 03

col 4: [ 2] c2 09

col 5: [ 7] 77 b40c11 01 01 01

col 6: [ 3] c24a46

col 7: [ 5] 53 4d 49 54 48

bindmp: 00 30 08 17 ff 0e cb c2 50 03 ca c2 09 cf 77 b40c11 01 01 01 cb c24a46 cd 53 4d 49 54 48

*0030表示为0x0030转为十进制为48,表示这一压缩行供给48行使用

*08表示列的数量,即为8

tab 0, row 1, @0x1ef5

tl: 31 fb: --H-FL-- lb: 0x0 cc: 8

col 0: [ 2] c1 15

col 1: *NULL*

col 2: [ 5] 434c45 52 4b

col 3: [ 3] c2 4e 59

col 4: [ 2] c20c

col 5: [ 7] 77 b7 010c01 01 01

col 6: [ 3] c24f4d

col 7: [ 5] 41 44 41 4d 53

bindmp: 00 30 08 17 ff 0e cb c2 4e 59 ca c20ccf 77 b7 010c01 01 01 cb c24f4d cd 41 44 41 4d 53

... ...

... ...

tab 0, row 23, @0x1f7b

tl: 5 fb: --H-FL-- lb: 0x0 cc: 1

col 0: [ 2] c1 15

2.2.4.1 data header部分

此部分是总结的部分记录了块中有多少行的数据列存储的顺序记录表中记录的条数及重复记录的条数等信息。

data_block_dump,data header at 0x1103ff07c

===============

tsiz: 0x1f80

hsiz: 0x5b0

pbl: 0x1103ff07c

bdba: 0x01000f14

76543210

flag=-0------ *flag0表示是压缩块

ntab=2 *ntab表述数据块中表的数量,普通表的数据块中这个值是1

而压缩表大于1

nrow=700 *nrow表示该数据块中的记录数,此项表明该块中含700条记录

frre=-1

fsbo=0x5b0

fseo=0x106a

avsp=0x2a

tosp=0x2a

r0_9ir2=0x0 *9ir2表示的是这项压缩功能起始的版本

mec_kdbh9ir2=0xe

76543210

shcf_kdbh9ir2=----------

76543210

flag_9ir2=--R---OC

fcls_9ir2[9]={ 0 32768 32768 32768 32768 32768 32768 32768 32768 }

perm_9ir2[8]={ 6 7 2 3 5 4 1 0 }*表示实际存储字段顺序也就是说后面物理存储的顺序COL6,COL7,COL2...

0x30:pti[0]nrow=24offs=0 *记号表中非重复的记录中有24

0x34:pti[1]nrow=676 offs=24 *重复的记录有676

0x38:pri[0]offs=0x1f14

... ...

... ...

0x5ac:pri[698] offs=0x106f

0x5ae:pri[699] offs=0x106a

2.2.4.2非重复的各条记录

24行的数据,部分数据省略掉

block_row_dump:

tab 0, row 0, @0x1f14

tl: 31 fb: --H-FL-- lb: 0x0 cc: 8

*fb->flag byte H->header F->first L->last

*cc->column count(列数量)

col 0: [ 2] c1 15 *列长度为2,类型为c115

col 1: *NULL*

col 2: [ 5] 434c45 52 4b

col 3: [ 3] c2 50 03

col 4: [ 2] c2 09

col 5: [ 7] 77 b40c11 01 01 01

col 6: [ 3] c24a46

col 7: [ 5] 53 4d 49 54 48

bindmp: 00 30 08 17 ff 0e cb c2 50 03 ca c2 09 cf 77 b40c11 01 01 01 cb c24a46 cd 53 4d 49 54 48

*0030表示为0x0030转为十进制为48,表示这一压缩行供给48行使用

*08表示列的数量,即为8

tab 0, row 1, @0x1ef5

tl: 31 fb: --H-FL-- lb: 0x0 cc: 8

col 0: [ 2] c1 15

col 1: *NULL*

col 2: [ 5] 434c45 52 4b

col 3: [ 3] c2 4e 59

col 4: [ 2] c20c

col 5: [ 7] 77 b7 010c01 01 01

col 6: [ 3] c24f4d

col 7: [ 5] 41 44 41 4d 53

bindmp: 00 30 08 17 ff 0e cb c2 4e 59 ca c20ccf 77 b7 010c01 01 01 cb c24f4d cd 41 44 41 4d 53

... ...

... ...

tab 0, row 23, @0x1f7b

tl: 5 fb: --H-FL-- lb: 0x0 cc: 1

col 0: [ 2] c1 15

2.2.4.3重复的各条记录

相同的记录会有同样的指针,例如在本例中,row1row 152349指向的都是同一个位置。

bindmp: 00 05 ca c1 15 *指向记号表中记录的指针,相同的记录同样的指针

tab 1, row 0, @0x1d99

tl: 5 fb: --H-FL-- lb: 0x0 cc: 8

col 0: [ 2] c1 15

col 1: *NULL*

col 2: [ 5] 434c45 52 4b

col 3: [ 3] c2 50 03

col 4: [ 2] c2 09

col 5: [ 7] 77 b40c11 01 01 01

col 6: [ 3] c24a46

col 7: [ 5] 53 4d 49 54 48

bindmp:2c00 01 08 00

tab 1, row 1, @0x1d94

tl: 5 fb: --H-FL-- lb: 0x0 cc: 8

col 0: [ 2] c11f

col 1: [ 2] c2 04

col 2: [ 8] 53 414c45 53 4d 41 4e

col 3: [ 3] c2 4d 63

col 4: [ 2] c2 11

col 5: [ 7] 77 b5 02 14 01 01 01

col 6: [ 3] c2 4b 64

col 7: [ 5] 414c4c45 4e

bindmp:2c00 01 08 07

... ...

... ...

tab 1, row 675, @0x106a

tl: 5 fb: --H-FL-- lb: 0x0 cc: 8

col 0: [ 2] c1 0b

col 1: *NULL*

col 2: [ 5] 434c45 52 4b

col 3: [ 3] c2 4e 53

col 4: [ 2] c2 0e

col 5: [ 7] 77 b6 01 17 01 01 01

col 6: [ 3] c2 50 23

col 7: [ 6] 4d 494c4c45 52

bindmp:2c00 01 08 0b

end_of_block_dump

End dump data blocks tsn: 4 file#: 4 minblk 3860 maxblk 3860

3段压缩的优缺点、限制及性能

3.1优点

* 节省存储空间:这也是ORACLE实现段数据压缩的目的所在,随着数据的海量,历史数据的不断的堆积,段压缩技术在节省空间的同时也节省了单位历史数据的存储成本。

* 性能会有提升:段压缩针对的都应该是历史数据,这样的数据的特点是海量、不变更一般只用于查询,这里所说的性能的提升是在CPU不是瓶颈的前提下,且是查询性能的提升。因为表段被压缩后其所占的数据块会大量的减少,单次的IO会读取更多的block,也因此会减少对buffer cache的占用。段压缩技术会提升IO的性能,如今cpu不断的加速,从双核到四核不断的加速,ibm p6cpu也已经问世,也因此时间换空间的优化技术也越来越流行。

3.2缺点及限制

* 会增加些额外的cpu的负担:上面已经提到,ORACLE段压缩技术是时间换空间的一种体现,存储空间的减少势必会导致建立压缩段和查询数据时压缩及解压缩时cpu的消耗。

* 表压缩不支持超过255

* BasicFile(相对于11g推出的SecureFiles而言)方式存储的LOB型数据段在表压缩时是不会被压缩的,11g推出的SecureFiles支持LOB的压缩,这方面可以参照11g的联机文档。

* ORACLE11g之前的版本只会在批量装载时对数据进行压缩:虽然在Oracle9i中引入了段压缩技术,但只能对批量装载操作(比如sql*loader直接路径装载,CTASinsertappend提示等)涉及的数据进行压缩,普通的DML操作的数据是无法压缩的,这应该是对于写操作的压缩难题没有解决的缘故。

* 索引组织表及含有overflow段的表或分区表是不支持表压缩的。

* 不能显示的(explicitly)hash分区及hashlist子分区定设定压缩选项,这些分区的压缩选项可以从表空间、表或分区的压缩属性继承过来。

* 外部表和是cluster组成部分的表是不支持压缩的。

* 段压缩技术适用于数据仓库这样的应用,一张表压缩后最好避免DML类型的操作,特别是update的操作,update操作会导致行迁移的发生,使得压缩表可能比原表占用的空间还大,所以切忌对压缩表做update操作,这样的技术应该用在合适的地方。

3.3性能

很多人担心表压缩后性能会有所降低,3.1中已经谈到了查询的性能会有所提升。关于这一点wanghai做了充份的测试,测试表明不论是全表扫描还是通过索引回表扫描压缩表的性能都不会比非压缩表差。至于dml,这是不推荐的,如果非要执行这样的操作,非批量装载操作insert操作之外的普通的insert操作的数据是不进行压缩的,因此压缩表的与常规表的insert性能是一样的。Update操作压缩表时会引发迁移,在浪费空间的同时也会牺牲性能。

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

转载于:http://blog.itpub.net/22630256/viewspace-1032891/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值