Oracle 11g EE版本中只有: Basic Table Compression ,而 AdvanceCompression Feature需要单独购买。
11g Advanced Compression 有如下特性:
1. Compression for Table Data
--支持了DML 语句的compress,下面会重点关注。
2. Compression for File Data
3. Compression for Backup Data
--包括RMAN和expdp/impdp.对数据泵,compress 是inline的,在impdp时不需要进行解压缩,直接导入即可。
4. Compression for Network Traffic
--在DG中使用,Redo在传输中被压缩和解压缩。
关于11g Advanced Compression,参考Oracle 的compression 白皮书:
http://www.oracle.com/technetwork/database/storage/advanced-compression-whitepaper-130502.pdf
这里我们只看Compressionfor Table Data。
The OracleDatabase 11g Advanced Compression Option introduces a comprehensive set ofcompression capabilities to help customers maximize resource utilizationand reduce costs. It allows IT administrators to significantly reduce theiroverall database storage footprint by enabling compression for all types ofdata – be it relational (table), unstructured (file), or backup data. Althoughstorage cost savings are often seen as the most tangible benefit ofcompression, innovative technologies included in the Advanced CompressionOption are designed to reduce resource requirements and technology costs forall components of your IT infrastructure, including memory and networkbandwidth.
Oracle has beena pioneer in database compression technology. Oracle Database 9i introducedBasic Table Compression several years ago that compressed data that was loadedusing bulk load operations. Oracle Database 11g Release 1 introduced a newfeature called OLTP Table Compression that allows data to be compressed duringall types of data manipulation operations, including conventional DML such asINSERT and UPDATE. In addition, OLTP Table Compression reduces the associatedcompression overhead of write operations making it suitable for transactionalor OLTP environments as well. OLTP Table Compression, therefore, extends thebenefits of compression to all application workloads.
--Oracle 是数据压缩技术的先驱,在Oracle 9i中就引入了Basic Table Compression。 9i中是使用bulk 进行装载时进行压缩。 到Oracle 11g,Table Compress特性进一步增强。
It should benoted that Basic Table Compression is a base feature of Oracle Database 11gEnterprise Edition (EE). OLTP Table Compression is apart of the Oracle Advanced Compression option, which requires a license inaddition to the Enterprise Edition.
注意:
Oracle 11g EE版本中只有: Basic Table Compression ,而 AdvanceCompression Feature需要单独购买。
Oracle’s OLTPTable Compression uses a unique compression algorithm specifically designed towork with OLTP applications. The algorithm works by eliminating duplicatevalues within a database block, even across multiple columns. Compressed blockscontain a structure called a symbol table that maintains compression metadata.When a block is compressed, duplicate values are eliminated by first adding asingle copy of the duplicate value to the symbol table. Each duplicate value isthen replaced by a short reference to the appropriate entry in the symboltable.
--Oracle 表压缩使用一个唯一的压缩算法。 该算法用来消除一个database block中的重复值,该重复值甚至可以跨多个列。 被压缩的blocks包含一个叫作symbol table的structure,该structure 用来维护压缩的元素。 当一个block 被压缩时,字段值第一次该被copy到symbol table中,然后每次的重复值都是被一个short reference 代替,该reference 指向symbol table 中对应的entry。
Through thisinnovative design, compressed data is self-contained within the database blockas the metadata used to translate compressed data into its original state isstored in the block. When compared with competing compression algorithms thatmaintain a global database symbol table, Oracle’s unique approach offerssignificant performance benefits by not introducing additional I/O whenaccessing compressed data.
通过这张图,可以清楚的看到compressed的block 比not compressed 的block 多了一个symbol Table。 正式因为该structure的使用,才使数据占用的空间降低很多。
The compressionratio achieved in a given environment depends on the nature of the data beingcompressed; specifically the cardinality of the data. In general, customers canexpect to reduce their storage space consumption by a factor of 2x to 4x byusing the OLTP Table Compression feature. That is, the amount of space consumedby uncompressed data will be two to four times larger than that of thecompressed data.
--压缩率由被压缩的数据性质决定,特别是重复值的数量。重复值越多,压缩率越高。 一般来说,通过压缩,可以降低2x 到 4x的空间的消耗。但是在uncompress时,还是需要增加原来的空间。
The benefits ofOLTP Table Compression go beyond just on-disk storage savings. One significantadvantage is Oracle’s ability to read compressed blocks directly without havingto first uncompress the block. Therefore, there is no measurable performance degradationfor accessing compressed data. In fact, in many cases performance may improvedue to the reduction in I/O
since Oracle will have to access fewerblocks. Further, the buffer cache will become more efficient by storing moredata without having to add memory.
--OLTP Table Compression 的好处不仅仅是存储空间的节省,另一个重要的影响Oracle 直接读压缩数据块的能力,因为不需要读uncompress的block, 在重复值越多的情况下,读compress 会降低I/O,从而提高性能,并且buffer cache因为存储更多的数据而更高效。
As stated above,OLTP Table Compression has no adverse impact on read operations. There isadditional work performed while writing data, making it impossible to eliminateperformance overhead for write operations. However, Oracle has put in asignificant amount of work to minimize this overhead for OLTP TableCompression. Oracle compresses blocks in batch mode rather than compressingdata every time a write operation takes place. A newly initialized blockremains uncompressed until data in the block reaches an internally controlledthreshold. When a transaction causes the data in the block to reach thisthreshold, all contents of the block are compressed. Subsequently, as more datais added to the block and the threshold is again reached, the entire block isrecompressed to achieve the highest level of compression.
--正如上面锁描述,Table Compression 对read 没有不利的影响。 但对write 操作时需要做一些附加的操作,正因如此,对compress block 不适合进行写操作。
Oracle 批处理的compress要优于每次写操作时进行压缩。当一个block 初始化时会保持uncompress状态,直到数据接近block 控制阀值,当某个事务导致数据达到这个threshold,block 里的所有数据都会被compressed。 随后,又更多的数据被添加进来,再次接近阀值,在次被压缩,直到整个block 达到最高的compression。
This processrepeats until Oracle determines that the block can no longer benefit fromfurther compression. Only transactions that trigger the compression of theblock will experience the slight compression overhead. Therefore, a majority ofOLTP transactions on compressed blocks will have the exact same performance asthey would with uncompressed blocks.
上图显示了block 不断被压缩的过程。
For new tablesand partitions, enabling OLTP Table Compression is as easy as simply CREATEingthe table or partition and specifying “COMPRESS FOR OLTP”. See the examplebelow:
CREATE TABLE emp(emp_id NUMBER, first_name VARCHAR2(128), last_name VARCHAR2(128)) COMPRESS FOROLTP;
--对于新表或者分区,可以在创建时指定参数:COMPRESS FOR OLTP.
For existingtables and partitions, there are three recommended approaches to enabling OLTPTable Compression:
--对于已经存在的表或者分区,可以使用如下三种方法来实现Table Compress:
This approach will enable OLTP TableCompression for all future DML -- however, the existing data in the table willremain uncompressed.
--启动compress后,之后的所有DML操作都会进行compress,但是对于已经存在的数据,会继续保持uncompressed。
This approach will enable OLTP TableCompression for future DML and also compress existing data. UsingDBMS_REDEFINITION keeps the table online for both read/write activity duringthe migration. Run DBMS_REDEFINITION in parallel for best performance.
--在线重定义支持以后的DML的压缩,同时也会compress 已经存在的数据。
Online redefinition will clone theindexes to the interim table during the operation. All the cloned indexes areincrementally maintained during the sync (refresh) operation so there is nointerrupt in the use of the indexes during, or after, the online redefinition.The only exception is when online redefinition is used for redefining apartition -- the global index is invalidated and needs to be rebuilt after theonline redefinition.
--在线重定义操作期间会clone索引到临时表。 这个和索引的online rebuild 类似。 但是online redefinition 会导致分区表的全局索引失效,需要在操作完成后进行重建。
参考我的blog:
Oracle alterindex rebuild 与 ORA-08104 说明
http://www.cndba.cn/Dave/article/1549
This approach will enable OLTP TableCompression for future DML and also compress existing data. While the table isbeing moved it is online for read activity but has an exclusive (X) lock – soall DML will be blocked until the move command completes. Run ALTER TABLE MOVEin parallel for best performance.
--该方法支持表以后的DML的压缩,同时也会已经存在的数据进行压缩,但是在move 期间会对表加上exclusive(X)锁,其他的DML操作会被block。 使用并行来执行ALTER TABLEMOVE 会增加操作的效率。
The ALTER TABLE...MOVE statement allowsyou to relocate data of a non-partitioned table, or of a partition of apartitioned table, into a new segment, and optionally into a differenttablespace. ALTER TABLE MOVE COMPRESS compresses the data by creating newextents for the compressed data in the tablespace being moved to -- it isimportant to note that the positioning of the new segment can be anywherewithin the datafile, not necessarily at the tail of the file or head of thefile. When the original segment is released, depending on the location of theextents, it may or may not be possible to shrink the datafile.
ALTER TABLE MOVE will invalidate anyindexes on the partition or table; those indexes will need to be rebuilt afterthe ALTER TABLE MOVE. Alternatively, the use of ALTER TABLE MOVE with theUPDATE INDEXES clause will maintain indexes (it places an exclusive (X) lock soall DML will be blocked until the move command completes).
--MOVE 操作会导致分区或者表上的所有失效,需要操作结束后rebuild 索引,或者在执行MOVE操作时加上UPDATE INDEXES,来维护索引。
Below are some best practices andconsiderations for the capabilities that are included as part of the AdvancedCompression Option:
The best test environment foreach Advanced Compression capability is where you can most closely duplicatethe production environment– this will provide the most realistic (pre- andpost- compression) performance comparisons.
Space usage reduction with OLTP TableCompression enabled gives the best results where the most duplicate data isstored (low cardinality). This is especially true for backups -- greatercompression will result in less data backed up and hence shorter recovery time.Sorting data (on the columns with the most duplicates) prior to bulk loads mayincrease the compression ratio.
Although CPU overhead is typicallyminimal, implementing Oracle Advanced Compression is ideal on systems withavailable CPU cycles, as compression will have additional, although minoroverhead for some DML operations.
Oracle Advanced Compression Advisor is aPL/SQL package that is used to estimate potential storage savings for OLTPTable Compression based on analysis of a sample of data. It provides a good estimateof the actual results that may be obtained after implementing Oracle AdvancedCompression’s OLTP Table compression feature. Oracle Advanced CompressionAdvisor, which supports Oracle Database 9i Release 2 through 11g Release 1, isavailable for free on the Oracle Technology Network website. The AdvancedCompression Advisor is built in to Oracle Database 11g Release 2.
OLTP Table Compression is NOT supportedfor use with tables that have more than 255 columns or that have LONG datatypes.
--OLTP TableCompression 不支持超过255个字段的表,或者表里有LONG 类型的字段。
LOBs are best stored in the OracleDatabase as SecureFiles LOBs, and if the customer has licensed the AdvancedCompression Option, they can use SecureFiles Compression and Deduplication to potentiallyreduce the amount of storage required for LOBs.
一般来说,数据压缩对OLAP 系统更有效,因为其数据很大。 但对现在的很多OLTP系统来说,数据也非常巨大,比如如下的几个用户:
OWNER SUM(BYTES/1024/1024)||'M'
------------------------------ -----------------------------------------
ECHN_HAND 781433.8125M
ECHNWEB 627652.75M
STAT_PRM 559465.875M
PRM 517039.4375M
加起来也有2T多的数据,如果不使用压缩或者转对数据进行转历史,那么会对磁盘空间带来不小的压力。而且数据压缩不仅仅是对磁盘空间的减少,从某些环境下,对性能也会有提高。
Oracle 是数据压缩技术的先驱,在Oracle 9i中就引入了Basic Table Compression。
Oracle 表压缩使用唯一压缩算法。该算法用来消除一个database block中的重复值,该重复值甚至可以跨多个列。 被压缩的blocks 会包含一个叫作symboltable的structure,该structure 用来维护压缩的元素。当一个block 被压缩时,字段值第一次该被copy到symbol table中,然后每次的重复值都是被一个short reference 代替,该reference 指向symbol table 中对应的entry。
压缩率由被压缩的数据性质决定,特别是重复值的数量。 重复值越多,压缩率越高。 一般来说,通过压缩,可以降低2x 到 4x的空间的消耗。 但是在uncompress时,还是需要增加原来的空间。
OLTP TableCompression 的好处不仅仅是存储空间的节省,另一个重要的影响Oracle 直接读压缩数据块的能力,因为不需要读uncompress的block, 在重复值越多的情况下,读compress 会降低I/O,从而提高性能,这种查询性能的提升体现在物理I/O和逻辑I/O上,而减少数据块扫描的同时,又降低了对CPU 资源的消耗,并且由于更少的数据块被加载到内存,所以对内存资源的消耗也会降低,从而使buffer cache可以存储更多的数据。
TableCompression 对read 没有不利的影响。 但对write操作时需要做一些附加的操作,正因如此,对compress block 不适合进行写操作。
Oracle 批处理的compress要优于每次写操作时进行压缩。当一个block 初始化时会保持uncompress状态,直到数据接近block 控制阀值(PCTFREE),当某个事务导致数据达到这个threshold,block 里的所有数据都会被compressed。 随后,又更多的数据被添加进来,再次接近阀值,在次被压缩,直到整个block 达到最高的compression。
对于新表或者分区,可以在创建时指定参数:COMPRESS FOR OLTP.如:
CREATE TABLE emp(emp_id NUMBER, first_name VARCHAR2(128), last_name VARCHAR2(128)) COMPRESS FOROLTP;
对于已经存在的表或者分区,可以使用如下三种方法来实现Table Compress:
(1)ALTER TABLE …COMPRESS FOR OLTP
启动compress后,之后的所有DML操作都会进行compress,但是对于已经存在的数据,会继续保持uncompressed。
表的COMPRESS参数在之前的blog有说明,参考:
Oracle Table创建参数 说明
http://blog.csdn.net/tianlesoftware/article/details/4954417
(2)OnlineRedefinition (DBMS_REDEFINITION)
在线重定义支持以后的DML的压缩,同时也会compress 已经存在的数据。
(3)ALTER TABLE …MOVE COMPRESS FOR OLTP
该方法支持表以后的DML的压缩,同时也会已经存在的数据进行压缩,但是在move 期间会对表加上exclusive(X)锁,其他的DML 操作会被block。使用并行来执行ALTER TABLE MOVE 会增加操作的效率。
MOVE操作会导致分区或者表上的所有失效,需要操作结束后rebuild 索引,或者在执行MOVE操作时加上UPDATE INDEXES,来维护索引。
注意:
OLTP Table Compression 不支持超过255个字段的表,或者表里有LONG 类型的字段。
上面提到的是对表进行压缩,实际上我们可以对堆表,分区表,索引,分区索引进行compression。当然,对应block中的重复值越多,压缩率越好。而对于主键索引,或者唯一性约束的索引来进行压缩,不但不能减少空间,反而会增加空间的消耗,因为使用compress 需要在block里创建一个symbol table 的结构来维护压缩。 如果记录中没有重复值,那么symboltable 就完全起不到作用。
以下的DML操作会进行数据压缩:
1. alter table move
2. create table as select
3. insert /*+append*/
4. sqlldr + direct path.
Consider Using Table Compression
http://docs.oracle.com/cd/E11882_01/server.112/e25494/tables002.htm#CJAGFBFG
创建表时使用COMPRESS关键字,COMPRESS关键字指示Oracle数据库尽可能以压缩的格式存储该表中的行。
SQL> create table ……compress;
修改普通表为压缩表:
SQL> alter table …… compress;
使用alter table .. move compress使一个已存在但未压缩的表转换为压缩表.
SQL> alter table tmp_test move compress;
取消表的压缩:
SQL> alter table …… nocompress;
使用alter table.. move nocompress来解压一个已经压缩的表:
SQL> alter table tmp_test move nocompress;
查看表级压缩:
确定一个表是否使用了压缩,查询user_tables,compression字段表明表是否被压缩.
SQL> select table_name,compression from user_tables wheretable_name= ' ';
注意:
启动compress后,之后的所有DML操作都会进行compress,但是对于已经存在的数据,会继续保持uncompressed。除非我们使用move compress。这里compress 的过程在前面有说明,当我们启动compress后, block 初始化时会保持uncompress状态,直到数据接近block 控制阀值(PCTFREE),当某个事务导致数据达到这个threshold,block 里的所有数据都会被compressed。 随后,又更多的数据被添加进来,再次接近阀值,在次被压缩,直到整个block 达到最高的compression。
在表空间级别上定义COMPRESS属性,既可以在生成时利用CREATE TABLESPACE来定义,也可以稍后时间利用ALTERTABLESPACE来定义。
COMPRESS属性具有继承特性。当在一个表空间中创建一个表时,它从该表空间继承COMPRESS属性。
表空间转换和取消压缩表空间
SQL> alter tablespace …… default compress;
SQL> alter tablespace …… default nocompress;
查看表空间级压缩:
确定是否已经利用COMPRESS对一个表空间进行了定义,可查询USER_TABLESPACES数据字典视图并查看DEF_TAB_COMPRESSION列
SQL> select tablespace_name,def_tab_compressionfrom user_tablespaces where tablespace_name=’ ’;
使用用于压缩表的类似方式来压缩物化视图。基于多个表的联接生成的物化视图通常很适于压缩,因为它们通常拥有大量的重复数据项。
SQL> create materialized view …… compress as select ……where ……;
可以使用ALTERMATERIALIZED VIEW命令来改变一个物化视图的压缩属性。注意;通常是在下一次刷新该物化视图时才会进行实际的压缩。
SQL> alter materialized view……compress;
在对已分区的表应用压缩时,可以有如下设置:
1.分区表的每个分区都可以独立压缩
2.有些时候,分区表在创建时不设置分区压缩属性,当某个分区需要压缩时,再独立进行压缩
3.如果在表级设置压缩属性的话,那么所有分区都会启动压缩功能,反正如果是某几个分区独立压缩,表级属性上什么也不写。
利用ALTER TABLE...MOVE PARTITION命令对此分区进行压缩:
SQL> alter table …… move partition …… compress;
要找出一个表中的哪些分区被压缩了,可以查询数据字典视图USER_TAB_PARTITIONS
SQL>select table_name, partition_name,compression fromuser_tab_partitions;
对已分区但未压缩的表(甚至带子分区)进行压缩,如果不能一步完成,那么:
1) SQL>alter table …… compress;
2) SQL>select 'alter table …… move subpartition '||subpartition_name||';' from user_tab_subpartitions where table_name like '……';
索引压缩分为2类:基本索引压缩和分区索引压缩
分区索引压缩注意事项:
1.分区表索引中不能对单个独立分区索引设置压缩,要么整体压缩要么不压缩,如果希望某几个分区不压缩,那么可以在修改成nocompress。
2.如果创建分区表索引时未设置压缩,以后都不能在设置了
注意:一般来说,对于索引,不建议使用压缩,因为根据索引的选择性,要求的重复值越低越好。对于主键或者唯一约束索引,就没有重复值。 如果对这种类型的索引使用压缩,不但不能节省空间,反而会增加索引空间的消耗。 因为在索引的Block里需要分配一个symbol table的结构来维护压缩信息。
修改表或索引的compress 属性,对已经存在的数据不会进行压缩。只有在向一个表中加裁/插入数据时,才会压缩数据。
只有在使用下面5种方法时,表中的数据才会被压缩存放:
Ø 直接路径的 sql*load,sqlldr 使用参数 direct path
Ø 带有/*+ append*/的 insert语句
Ø create table表名 compress as select..
Ø 并行insert, insert /*+ append */
注:常规 insert into不压缩数据
Ø alter table move
(1)alter table 表名move compress
(2)alter table 表名move partition 分区名 compress
除表可以压缩外,分区表可以压缩,索引可以压缩,物化视图也可以压缩。注:除索引外,压缩属性可以继承表空间的压缩属性。表空间改成压缩的:
SQL>alter tablespace dave default compress;
查看对象block信息使用show_space过程:
OracleShow_space 过程 使用示例 与 注释
http://www.cndba.cn/Dave/article/410
测试平台:
SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise EditionRelease 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
CORE 11.2.0.3.0 Production
TNS for Linux: Version 11.2.0.3.0 -Production
NLSRTL Version 11.2.0.3.0 - Production
SQL> create table ctas_nocompress asselect * from dba_objects;
Table created.
SQL> create table ctas_compress compressas select * from dba_objects;
Table created.
SQL> set serveroutput on
SQL> execshow_space('ctas_nocompress','t');
TotalBlocks............................1152
TotalBytes.............................9437184
Unused Blocks...........................81
Unused Bytes............................663552
Last Used Ext FileId....................1
Last Used ExtBlockId...................98176
Last Used Block.........................47
PL/SQL procedure successfully completed.
SQL> execshow_space('ctas_compress','t');
Total Blocks............................384
TotalBytes.............................3145728
Unused Blocks...........................73
UnusedBytes............................598016
Last Used Ext FileId....................1
Last Used Ext BlockId...................98560
Last Used Block.........................55
PL/SQL procedure successfully completed.
--通过以上对比,可以验证,只有使用create table table_namecompress as 的时候才能压缩。
SQL> create table tab_inst as select *from dba_objects where 1=2;
Table created.
SQL> create table tab_inst_comp compressas select * from dba_objects where 1=2;
Table created.
SQL> insert into tab_inst select * fromdba_objects;
75226 rows created.
SQL> commit;
Commit complete.
SQL> insert /*+append*/ intotab_inst_comp select * from dba_objects;
75226 rows created.
SQL> commit;
Commit complete.
SQL> exec show_space('tab_inst');
TotalBlocks............................1152
TotalBytes.............................9437184
Unused Blocks...........................83
UnusedBytes............................679936
Last Used Ext FileId....................1
Last Used ExtBlockId...................100736
Last Used Block.........................45
PL/SQL procedure successfully completed.
SQL> exec show_space('tab_inst_comp','t');
TotalBlocks............................1024
TotalBytes.............................8388608
Unused Blocks...........................61
UnusedBytes............................499712
Last Used Ext FileId....................1
Last Used Ext BlockId...................100608
Last Used Block.........................67
PL/SQL procedure successfully completed.
注意, 这里我们使用insert /*+append*/ into ,有一定的压缩,从1152到1024. 但是效果没有我们3.1小节使用create table compress 的明显。 当然我这里测试的表比较小,如果表基数比较大,这个也可以很可观的。
对我们3.2 中的表进行movecompress:
SQL> alter table tab_inst_comp movecompress;
Table altered.
SQL> exec show_space('tab_inst_comp');
TotalBlocks............................384
TotalBytes.............................3145728
Unused Blocks...........................73
UnusedBytes............................598016
Last Used Ext FileId....................1
Last Used ExtBlockId...................101120
Last Used Block.........................55
PL/SQL procedure successfully completed.
这里的效果就很明显了。
在前面几节测试了compress在block上的变化,这里直接从表的大小上来看。
现在有2个compress 的表:tab_inst_comp,ctas_compress。
可以使用如下SQL 查看表和索引的compress属性:
SQL>selectowner,table_name,compression from dba_tables;
SQL>selectowner,index_name,compression from dba_indexes;
SQL> set lin 120
SQL> col owner for a15
SQL> col table_name for a20
SQL> select owner,table_name,compressionfrom dba_tables where table_name=upper('&table_name');
Enter value for table_name: tab_inst_comp
old 1: select owner,table_name,compression from dba_tables wheretable_name=upper('&table_name')
new 1: select owner,table_name,compression from dba_tables wheretable_name=upper('tab_inst_comp')
OWNER TABLE_NAME COMPRESSION
--------------- ------------------------------------
SYS TAB_INST_COMP ENABLED
SQL> /
Enter value for table_name: ctas_compress
old 1: select owner,table_name,compression from dba_tables wheretable_name=upper('&table_name')
new 1: select owner,table_name,compression from dba_tables wheretable_name=upper('ctas_compress')
OWNER TABLE_NAME COMPRESSION
--------------- ------------------------------------
SYS CTAS_COMPRESS ENABLED
--查看2张表的大小:
SQL> selectsegment_name,segment_type,bytes/1024/1024 from dba_segments where segment_namein (upper('ctas_compress'),upper('tab_inst_comp'))
2 /
SEGMENT_NAME SEGMENT_TYPE BYTES/1024/1024
------------------------------ -----------------------------------
TAB_INST_COMP TABLE 3
CTAS_COMPRESS TABLE 3
SQL> alter table tab_inst_compnocompress;
Table altered.
--注意这里的nocompress 并没有让表在大小上发生变化:
SQL> selectsegment_name,segment_type,bytes/1024/1024 from dba_segments where segment_namein (upper('ctas_compress'),upper('tab_inst_comp'));
SEGMENT_NAME SEGMENT_TYPE BYTES/1024/1024
-------------------------------------------------- ---------------
TAB_INST_COMP TABLE 3
CTAS_COMPRESS TABLE 3
SQL> alter table tab_inst_comp move;
Table altered.
--我们执行move 之后,表的大小就从3M变成了8M。
SQL> select segment_name,segment_type,bytes/1024/1024from dba_segments where segment_name in(upper('ctas_compress'),upper('tab_inst_comp'));
SEGMENT_NAME SEGMENT_TYPE BYTES/1024/1024
-------------------------------------------------- ---------------
TAB_INST_COMP TABLE 8
CTAS_COMPRESS TABLE 3
因此,对对象进行nocompress可以执行:
SQL>alter table tab_inst_comp movenocompress;
这样还原了表实际的大小。
还有就是我们对表进行update 的时候,也会对相关的记录进行解压缩,并且解压缩后的数据不会在进行压缩。 这里我们对CTAS_COMPRESS进行测试。
SQL> set timing on
Elapsed: 00:00:00.02
SQL> select count(1) from ctas_compress;
COUNT(1)
----------
75224
Elapsed: 00:00:00.03
SQL> create table ctas as select * fromdba_objects;
Table created.
Elapsed: 00:00:00.76
SQL> update ctas set owner='dave';
75227 rows updated.
Elapsed: 00:00:09.24
--未压缩的情况,update 7w条记录,用时9秒。
SQL> commit;
Commit complete.
Elapsed: 00:00:00.08
SQL> update CTAS_COMPRESS setowner='dave';
75224 rows updated.
Elapsed: 00:01:46.63
--使用表压缩,更新花了46秒。 是未压缩时的5倍。如果表更大,那么时间就会更长。
SQL> selectsegment_name,segment_type,bytes/1024/1024 from dba_segments where segment_namein (upper('ctas_compress'),upper('tab_inst_comp'));
SEGMENT_NAME SEGMENT_TYPE BYTES/1024/1024
-------------------------------------------------- ---------------
TAB_INST_COMP TABLE 8
CTAS_COMPRESS TABLE 10
--并且,update 之后,表被完全解压缩了。
以上测试也说明,为什么对update 比较频繁的表不建议使用压缩。而只对read多的表进行压缩。
SQL> create table tb_par(object_id,object_name)
2 partition by range (object_id)
3 (
4 partition tb_par01 values lessthan (10000),
5 partition tb_par02 values lessthan (20000),
6 partition tb_par03 values lessthan (30000),
7 partition tb_par04 values lessthan (40000),
8 partition tb_par05 values lessthan (50000),
9 partition tb_par_max valuesless than (maxvalue)
10 )
11 as selectobject_id,object_name from dba_objects;
Table created.
SQL> select count(*) from tb_par;
COUNT(*)
----------
75234
由于是分区表,查询表属性是否压缩的时候,出现为空,必须查分区信息,如下:
SQL> col partition_name for a20
SQL> selecttable_name,compression,PARTITIONED from user_tables wheretable_name=UPPER('tb_par');
TABLE_NAME COMPRESSION PARTIT
-------------------- ----------------------
TB_PAR YES
SQL> select partition_name,compressionfrom user_tab_partitions where table_name=UPPER('tb_par');
PARTITION_NAME COMPRESSION
-------------------- ----------------
TB_PAR01 DISABLED
TB_PAR02 DISABLED
TB_PAR03 DISABLED
TB_PAR04 DISABLED
TB_PAR05 DISABLED
TB_PAR_MAX DISABLED
6 rows selected.
(1)定义表级压缩属性,此时所有分区都压缩:
SQL>altertable tb_par compress;
Tablealtered
观察分区属性:
SQL> select partition_name,compressionfrom user_tab_partitions where table_name=UPPER('tb_par');
PARTITION_NAME COMPRESSION
-------------------- ----------------
TB_PAR01 ENABLED
TB_PAR02 ENABLED
TB_PAR03 ENABLED
TB_PAR04 ENABLED
TB_PAR05 ENABLED
TB_PAR_MAX ENABLED
6 rows selected.
(2)对某个分区表空间建立压缩,不能将所有表属性设置为compress。
SQL> alter table tb_par nocompress;
Table altered.
SQL> select partition_name,compressionfrom user_tab_partitions where table_name=UPPER('tb_par');
PARTITION_NAME COMPRESSION
-------------------- ----------------
TB_PAR01 DISABLED
TB_PAR02 DISABLED
TB_PAR03 DISABLED
TB_PAR04 DISABLED
TB_PAR05 DISABLED
TB_PAR_MAX DISABLED
6 rows selected.
SQL> alter tabletb_par modify partition tb_par01 compress;
Table altered.
SQL> alter table tb_par modify partitiontb_par02 compress;
Table altered.
SQL> alter tabletb_par move partition tb_par03 compress;
Table altered.
--注意这里使用了move
SQL> select partition_name,compression from user_tab_partitions wheretable_name=UPPER('tb_par');
PARTITION_NAME COMPRESSION
-------------------- ----------------
TB_PAR01 ENABLED
TB_PAR02 ENABLED
TB_PAR03 ENABLED
TB_PAR04 DISABLED
TB_PAR05 DISABLED
TB_PAR_MAX DISABLED
6 rows selected.
注意,分区索引压缩注意事项:
1.分区表索引中不能对单个独立分区索引设置压缩,要么整体压缩要么不压缩,如果希望某几个分区不压缩,那么可以在修改成nocompress。
2.如果创建分区表索引时未设置压缩,以后都不能在设置了
没有压缩的索引:
SQL>createindex tb_par_indx on tb_par(object_id) local;
Indexcreated.
查看索引压缩的属性:
SQL>selectindex_name,compression from user_indexes where table_name=UPPER('tb_par');
INDEX_NAME COMPRESSION
------------------------------ -----------
TB_PAR_INDX DISABLED
SQL>selectpartition_name,compression from user_ind_partitions whereindex_name=UPPER('tb_par_indx');
PARTITION_NAME COMPRESSION
-----------------------------------------
TB_PAR01 DISABLED
TB_PAR02 DISABLED
TB_PAR03 DISABLED
TB_PAR04 DISABLED
TB_PAR05 DISABLED
TB_PAR_MAX DISABLED
6rows selected
SQL> alter index tb_par_indx rebuildpartition tb_par04 compress;
alter index tb_par_indx rebuild partitiontb_par04 compress
*
ERROR at line 1:
ORA-28659: COMPRESS must be specified atobject level first
必须首先在对象级指定 COMPRESS
报错,压缩必须首先在对象级别指定,这个意思是必须先设置表级索引为压缩。必须创建分区表索引时一次性指定好压缩属性,以后才能对独立分区索引压缩进行修改,必须先设置压缩,然后再进行取消压缩属性。
SQL> alter index tb_par_indx rebuildcompress;
alter index tb_par_indx rebuild compress
*
ERROR at line 1:
ORA-14086: a partitionedindex may not be rebuilt as a whole
先drop 索引,在新建:
SQL> drop index tb_par_indx;
Indexdroped
SQL>createindex tb_par_indx_compress on tb_par(object_id) local compress;
Indexcreated
SQL>selectindex_name,compression from user_indexes where table_name=UPPER('tb_par');
INDEX_NAME COMPRESSION
-----------------------------------------
TB_PAR_INDX_COMPRESS ENABLED
SQL>selectpartition_name,index_name,compression from user_ind_partitions whereindex_name=UPPER('TB_PAR_INDX_COMPRESS');
PARTITION_NAME INDEX_NAME COMPRESSION
------------------------------------------------------------ -----------
TB_PAR01 TB_PAR_INDX_COMPRESS ENABLED
TB_PAR02 TB_PAR_INDX_COMPRESS ENABLED
TB_PAR03 TB_PAR_INDX_COMPRESS ENABLED
TB_PAR04 TB_PAR_INDX_COMPRESS ENABLED
TB_PAR05 TB_PAR_INDX_COMPRESS ENABLED
TB_PAR_MAX TB_PAR_INDX_COMPRESS ENABLED
6rows selected
独立分区索引取消压缩:
SQL> alter index TB_PAR_INDX_COMPRESS rebuild partitiontb_par04 nocompress;
Indexaltered
SQL> alter index TB_PAR_INDX_COMPRESS rebuildpartition tb_par05 nocompress;
Indexaltered
SQL> alter index TB_PAR_INDX_COMPRESS rebuildpartition tb_par_max nocompress;
Indexaltered
SQL> select partition_name,index_name,compressionfrom user_ind_partitions where index_name=UPPER('TB_PAR_INDX_COMPRESS');
PARTITION_NAME INDEX_NAME COMPRESSION
------------------------------------------------------------ -----------
TB_PAR01 TB_PAR_INDX_COMPRESS ENABLED
TB_PAR02 TB_PAR_INDX_COMPRESS ENABLED
TB_PAR03 TB_PAR_INDX_COMPRESS ENABLED
TB_PAR04 TB_PAR_INDX_COMPRESS DISABLED
TB_PAR05 TB_PAR_INDX_COMPRESS DISABLED
TB_PAR_MAX TB_PAR_INDX_COMPRESS DISABLED
6rows selected
注意:
在前面的内容也说过,索引本身占据的空间比较小,除非超大数据量表,否则不建议使用压缩,因为各方面维护的性能消耗高于压缩带来的性能提升。
---------------------------------------------------------------------------------------
版权所有,文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!
QQ:492913789
Email:[email protected]
Blog: http://www.cndba.cn/dave
Weibo: http://weibo.com/tianlesoftware
Twitter: http://twitter.com/tianlesoftware
Facebook: http://www.facebook.com/tianlesoftware
Linkedin: http://cn.linkedin.com/in/tianlesoftware