HelloDBA [English]
搜索Internet 搜索 HelloDBABA
  Oracle技术站。email: fuyuncat@gmail.com  MSN: fuyuncat@hotmail.com   acoug  acoug 

数据段压缩(Data Segment Compression)浅析

[English]

作者: fuyuncat

来源: www.HelloDBA.com

日期: 2005-08-07 14:50:13

分享到  新浪微博 腾讯微博 人人网 i贴吧 开心网 豆瓣 淘宝 推特 Facebook GMail Blogger Orkut Google Bookmarks

1.   什么是数据段压缩

数据段压缩,又称为“块级压缩”,是Oracle 9.2 中出现的新特性。他对于数据仓库和那些只需要读的大表来说很有用。数据段压缩可以使存储空间减少,又可以提高查询速度(需要读入的数据块更少)。

压缩可以在创建表时指定,也可以通过修改表来激活。

CREATE TABLE CMPTest ( a number,

                                      b varchar2(20),

                                      c char(20))

             TABLESPACE ASSMDEMO

             NOLOGGING

             COMPRESS

             PCTFREE 0;

 

ALTER TABLE CMPTest COMPRESS;

 

此外,还可以对表空间指定压缩。

CREATE TABLESPACE tbs_compress DATAFILE 'tbscomp01.dat' SIZE 20M

               DEFAULT COMPRESS STORAGE ( … );

 

 

对于不更新/删除的大数据表,可以使用压缩,也可以使用分区。最好办法就是将老的数据压缩在一个分区表中。举例:

ALTER TABLE MYPARTTABLE MOVE PARTITION JAN04 TABLESPACE COMP_DATA COMPRESS PCTFREE 0;

          修改过表后,还是需要执行压缩命令进行压缩。

ALTER TABLE MYPARTTABLE MODIFY PARTITION JAN04 REBUILD UNUSABLE LOCAL INDEXES;

 

          数据段压缩的另一个适用的地方就是物化视图,因为物化视图一般都是只读的。

CREATE MATERIALIZED VIEW LOG ON cmptest
   WITH ROWID
   INCLUDING NEW VALUES;

CREATE MATERIALIZED VIEW CMP_MV
    tablespace assmdemo
    nologging
    compress
    pctfree 0
    REFRESH WITH ROWID AS SELECT * FROM cmptest x;

 

ALTER MATERIALIZED VIEW CMP_MV COMPRESS;

          当物化视图被刷新的时候,数据会压缩。

 

数据压缩对于用户来说是透明的。用户还是使用原来的查询语句进行查询。

 

 

查看表、索引或者物化视图是否压缩,可以通过以下语句:

SELECT table_name, compression FROM dba_tables;

select table_name, index_name, compression from dba_indexes
SELECT table_name, partition_name, compression FROM dba_tab_partitions;

 

2.   压缩是如何实现的

·         通过将数据块中的重复数据消除来实现压缩。

但是这种压缩只会压缩重复的数据字段/记录数据,而不会对一条字段/记录内的重复数据进行压缩。

 

·         一个数据块中字段或记录的所有重复数据只在数据块的开始处存储一次,这个地方就被称为这个数据块的记号表(Symbol Table)。

对于长字符串来说,除非字符串完全匹配,否则不会被压缩。

 

·         那些重复的数据都被一个指向记号表的短指引所代替。

除了在开始处有记号表外,压缩数据块和普通数据块都一样的。

 

·         只有当数据块被直接/批量载入/插入时,Oracle才会压缩数据。直接载入数据的语句有以下几种方式:

·         通过使用APPEND提示插入数据

·         通过使用PARALLEL提示插入数据(并行查询)

·         CREATE TABLE AS

·         SQL*LOAD时使用DIRECT LOAD

 

通过普通的INSERT语句插入数据时,是不会压缩数据的。

 

数据库中已有也可以通过ALTER TABLE … MOVE来压缩。这一操作会给表加上一个排他锁以阻止任何其他更新、插入操作。

如果这种方式不合适,可以使用Oracle的在线重整工具(dbms_redefinition包)来实现。

 

·         压缩数据可以通过INSERT, UPDATEDELETE命令操作,但是,没有使用批量插入或载入方式的数据不会被压缩。

数据段压缩比较适用于那些不要更新和删除数据的大表。如果对已经压缩的数据进行了UPDATE/DELETE操作,将结束对数据的压缩,从而占用更多的空间——在UPDATE时,Oracle会解压缩数据行,重新插入数据;而DELETE会充满那些空闲空间,使空闲空间不够插入下一条数据。直接载入数据的插入方式一般在高水位(HWM)以上载入数据。

压缩表测试:

SQL> CREATE TABLE cmptest(a NUMBER,

  2                       b VARCHAR2(20),

  3                       c CHAR(20))

  4         tablespace

  5         assmdemo

  6         nologging

  7         pctfree 0;

 

Table created.

 

SQL> BEGIN

  2    FOR i IN 1 .. 10000 LOOP

  3      INSERT INTO cmptest VALUES (mod(i,10), to_char(mod(i,10) * 1000), to_char(mod(i,10) * 1000));

  4    END LOOP;

  5  &nbs