Oracle 10g数据表压缩的一些细节(上)
在Oracle 11g中,Advanced Compression是一个重要引入的新特性。Advanced Compression针对OLTP下的数据对象、Dataguard Redo Log等进行了较大程度的优化。在笔者之前的文章中,也针对此项特性进行了浅析。
目前,还有很多系统是运行在Oracle 10g乃至9i下,对这些系统而言,Oracle压缩有一些什么特性呢?本篇一起来探讨。 1、环境准备 我们选择Oracle 10gR2作为环境,同时准备原始数据表t_source,作为参照对象。
SQL> select * from v$version; BANNER ---------------------------------------------------------------- Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod PL/SQL Release 10.2.0.1.0 - Production CORE10.2.0.1.0Production 准备数据,观察在未使用10g压缩特性情况下,数据空间使用情况。 SQL> create table t_source as select * from dba_objects where wner='SCOTT' or wner='SYSMAN'; Table created SQL> select count(*) from t_source; COUNT(*) ---------- 1367 SQL> exec dbms_stats.gather_table_stats(user,'T_SOURCE',cascade => true); PL/SQL procedure successfully completed --段级别空间使用分析 SQL> select HEADER_FILE,HEADER_BLOCK,BYTES,BLOCKS,EXTENTS from dba_segments where wner='SCOTT' and segment_name='T_SOURCE'; HEADER_FILE HEADER_BLOCKBYTESBLOCKSEXTENTS ----------- ------------ ---------- ---------- ---------- 419196608243 SQL> select NUM_ROWS,Compression from dba_tables where wner='SCOTT' and table_name='T_SOURCE'; NUM_ROWSBLOCKS COMPRESSION ---------- ---------- ----------- 136723DISABLED 在利用所有行rowid情况,分析每个数据块的平均容纳行数。 SQL> select dbms_rowid.rowid_relative_fno(rowid) fno,dbms_rowid.rowid_block_number(rowid) bno,count(*) from t_source group by dbms_rowid.rowid_relative_fno(rowid),dbms_rowid.rowid_block_number(rowid) order by bno; FNOBNOCOUNT(*) ---------- ---------- ---------- 42046 42176 42276 42374 42478 4410573 4410671 4410771 4410873 4410977 4411076 4411174 4411273 4411477 4411574 4411675 4411745 4411981 4412077 19 rows selected SQL> select EXTENT_ID,FILE_ID,BLOCK_ID,BLOCKS from dba_extents where wner='SCOTT' and segment_name='T_SOURCE'; EXTENT_IDFILE_IDBLOCK_IDBYTESBLOCKS ---------- ---------- ---------- ---------- ---------- 0417655368–第一个分区 144105655368 244113655368 从上面准备的数据表t_source的情况看,在没有使用压缩的情况下分配三个分区共24个数据块。1367条记录分布在19个数据块上,平均每个数据块容纳大约70-80行记录。 2、压缩表建立实验 下面建立压缩数据表。在建表的第一分区分配的时候,就采用压缩方式进行。 SQL> create table t_compresscompressas select * from t_source; 44123131072162 136711ENABLED 我们当创建数据表就指定compress选项,数据表创建后就是压缩属性的。相同的数据量,只分配了2个分区。下面看具体行的使用情况。 44124178 44125199 44126177 44127197 44128189 44129185 44130207 4413135 8 rows selected 具体行在块的分配上,只用到了8个数据块进行存储。平均每个数据块容纳数据行接近200行。 说明:当我们在创建数据表的时候,就指定了compress选项。那么直接进行CATS插入的时候,压缩功能开启。同时,压缩效果较优。 注意:我们这里面使用的是CATS方式插入数据,而不是日常OLTP方式。两种方式差异显著。 3、变化分配数据插入实验 CATS方式是一种“压实”的插入方式。如果我们在变化过程中改变了数据表的压缩选项,空间分配情况会如何呢? 我们首先准备一个数据表,非压缩状态下插入过一部分的数据。 --插入一部分数据; SQL> create table t_sample as select * from t_source where mod(object_id,2)=0; SQL> select count(*) from t_sample; 695 44139131072162 SQL>select NUM_ROWS,Compression from dba_tables where wner='SCOTT' and table_name='T_SAMPLE'; 69513DISABLED 4414080 4414175 4414274 4414371 4414474 4414574 4414675 4414774 4414879 4414919 10 rows selected 分配情况和t_source的趋势相似。我们修改数据表属性。 SQL> alter table t_sample compress; Table altered 44139131072162 69513ENABLED 注意:此时我们修改了数据表属性,变化为compress。但是,现有数据并没有被压缩,而是保留为原有的情况。平均块容量为80左右个数据行,而非压缩下的上百行。 笔者此时猜想了一种可能,有没有在内部已经进行了空间重排,形成行链接模式。经过测试,发现没有行链接。而且在修改数据表compress属性的时候,执行时间也没有进行复杂变化的机会。 那么,我们接下来插入剩下的数据,使用OLTP方式。 SQL> insert into t_sample select * from t_source where mod(object_id,2)=1; 672 rows inserted SQL> commit; Commit complete 44139196608243 136723ENABLED 4415074 4415178 4415275 4416274 4416375 4416477 4416569 4416772 4416878 19 rows selected 注意:此时虽然是压缩模式,但是使用OLTP insert方式后,数据表空间并没有节省!新分配空间,依然是使用非压缩方式——这点可以从块行容量上看出来。 解决方法——Move操作 解决的方法,我们可以采用move移动。Move是一种对数据表物理存储进行重排的过程,相当于在另一个磁盘上进行数据表重新组织,对应的空间乃至段头都要发生变化。Move是我们经常使用的降低HWM的方法。 SQL> alter table t_sample move; 44171131072162 44172173 44173173 44174170 44175179 44176173 44177166 44178182 44179151 结论,我们发现空间被压缩,块行容量增加。 上面的实验,告诉我们几个结论: üCompress是数据段的一个属性。当我们单纯进行compress和nocompress切换的时候,数据已经分配空间是不会发生变化的; ü即使在compress的数据表,当我们进行常规OLTP数据插入的时候,是不会应用压缩选项的; üMove操作通过重新促使系统进行数据空间分配的配比,可以应用实现compress的结果——注意是结果,数据表被压缩! 下面我们通过几个极端情况实验,继续分析10gR2的Compression。 Oracle 10g数据表压缩的一些细节(下) 3、极端情况实验(1) 那么,上面我们验证数据compress选项切换无效,是不是和我们已经分配过的记录有关系呢?我们首先建立一张空表。 SQL> create table t_sample1 as select * from t_source where 1=0; SQL>exec dbms_stats.gather_table_stats(user,'T_SAMPLE1',EXTENTS from dba_segments where wner='SCOTT' and segment_name='T_SAMPLE1'; 441396553681 00DISABLED 我们创建空表,没有记录,但是默认有一个分区分配过来。 SQL> alter table t_sample1 compress; 00ENABLED SQL> insert into t_sample1 select * from t_source; 1367 rows inserted 136720 ENABLED 依然是使用三个分区,依然是没有进行压缩。 SQL> alter table t_sample1 move; 44187131072162 136711 ENABLED 结论:即使没有一行数据插入的情况下,我们使用compress的数据表,利用OLTP方式插入,也不能实现压缩。依然需要手工的压缩过程。 4、极端情况实验(2) 对实验数据表t_sample1继续插入数据时,新分配的数据块是可能应用压缩格式的。 此时,数据行会出现部分压缩的现象。 44187262144324 273431 ENABLED 4413883 4413985 4414083 4414181 4414284 4414379 4414479 4414883 4414983 4415088 4415188 4415227 44188193 44189184 44190184 44191177 44192188 44193199 44194199 4419543 4419684 4419782 4419886 4419982 4420090 25 rows selected 在我们持续增加数据的时候,会出现一定的压缩情况。 44211196608243 273419 ENABLED 44212193 44213184 44214184 44215177 44216188 44225199 44226199 44227191 44228191 44229178 44230198 44231174 44232185 44490199 4449194 15 rows selected 通过move过程,实现完全压缩。 5、实现压缩的insert方式 从上面一系列实验中,我们可以看出Oracle 10g Compression对OLTP方式插入数据压缩效果较差。但是,在进行Direct Insert方法的时候,Compression的效果是可以的。 SQL> create table t_source as select * from dba_objects where wner='SYS'; 45395314572838418 22946327DISABLED 新原数据表没有压缩,共占用384个块,18个extent分区。下面建立一个新的数据表t_compress,采用压缩配置。 --建立空数据表; SQL> create table t_compress as select * from dba_objects where 1=0; 00 DISABLED 开启压缩选项。 SQL> alter table t_compress compress; 00 ENABLED 之后采用direct insert方式插入数据。 SQL> insert /*+append */into t_compress select * from t_source; 22946 rows inserted 22946139ENABLED 46835209715225617 可见,在10R2中,压缩主要是针对那些稳定数据。如果操作是频繁的增加修改和删除的OLTP操作,压缩是不进行或者效果很差的。 6、结论
从上面的实验中,我们可以看出:Oracle 10R2中的压缩技术主要是针对稳定数据表而言的。如果数据表很大,而且不会频繁的进行增加修改和删除操作,我们推荐使用压缩功能。如果我们对一个压缩表进行OLTP方式操作,压缩效应是不明显的。只有在Direct Insert等特殊的操作中,压缩才能体现出来。 Oracle 11g带给我们的Advanced Compression新特性,其中的Compression For OLTP在一定程度上缓解了这个难题。 再次说明,我们的解决方案,要依据版本、效果和特性进行。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |