在 Oracle 数据库云服务器(Exadata)上实现混合列式压缩(Hybrid Columnar Compression)

Tags: database oracle

混合列式压缩(Hybrid Columnar Compression)是一种压缩方式,用来压缩存储在 Oracle Exadata storage 上的表数据,除了 Exadata 还包括 Axiom、SPARC SuperCluster 以及 Sum ZFS Storage Appliance。如果你在其他系统上使用这种压缩方式,你会得到以下提示信息:

SQL> alter table emp move compress for query high;
alter table emp move compress for query high
            *
ERROR at line 1:
ORA-64307: hybrid columnar compression is not supported for tablespaces on this storage type

SQL>

"this storage tpye" 的意思是,不是上面列出的存储类型中的一种。

HCC 的工作方式与 Basic 和 OLTP 压缩方式不同,它会将数据重新组织到一个压缩单元中(Compression Units, CU)。HCC 有两种基本类型:QUERY(Warehouse compression) 和 ARCHIVE,每种类型都有 HIG 和 LOW 选项。我们将先讨论 Query type,然后讨论 ARCHIVE type。

Query(Warehouse compression)

这种压缩方式是两种压缩方式中相对温和的,但它仍然比 OLTP 压缩方式的效率高。我们首先使用 query high 来压缩我们的 EMP 表:

SQL> 
SQL> --
SQL> -- Current storage for the EMP table
SQL> -- (this is simply a test table for this example)
SQL> --
SQL> select segment_name, sum(bytes) total_space
  2  from user_segments
  3  group by segment_name;

SEGMENT_NAME                        TOTAL_SPACE
----------------------------------- -----------
DEPT                                      65536
DUMMY                                     65536
EMP                                   713031680
EMP_IDX                               478150656
SALGRADE                                  65536

Elapsed: 00:00:00.82
SQL> 
SQL> --
SQL> -- Compress the table for query high (use HCC)
SQL> --
SQL> -- Note elapsed time to compress
SQL> --
SQL> alter table emp move compress for query high;

Table altered.

Elapsed: 00:00:35.65
SQL> 
SQL> --
SQL> -- Index is now invalid
SQL> --
SQL> -- Must rebuild to make it usable
SQL> --
SQL> -- Note elapsed time
SQL> --
SQL> alter index emp_idx rebuild;

Index altered.

Elapsed: 00:01:13.70
SQL> 
SQL> --
SQL> -- Current compression type, storage for table/index
SQL> -- initially after compression is enabled
SQL> --
SQL> select table_name, compression, compress_for
  2  from user_tables;

TABLE_NAME                     COMPRESS COMPRESS_FOR
------------------------------ -------- ------------
DEPT                           DISABLED
BONUS                          DISABLED
SALGRADE                       DISABLED
DUMMY                          DISABLED
EMP                            ENABLED  QUERY HIGH

Elapsed: 00:00:00.20
SQL> 
SQL> select segment_name, sum(bytes) total_space
  2  from user_segments
  3  group by segment_name;

SEGMENT_NAME                        TOTAL_SPACE
----------------------------------- -----------
DEPT                                      65536
DUMMY                                     65536
EMP                                     8388608
EMP_IDX                               260046848
SALGRADE                                  65536

Elapsed: 00:00:00.03
SQL>

压缩后的大小比 Basic 和 OLTP 压缩方式小很多。即使 Query Low 压缩的压缩结果也比 OLTP 小:

SQL> 
SQL> --
SQL> -- Initial storage
SQL> --
SQL> select segment_name, sum(bytes) total_space
  2  from user_segments
  3  group by segment_name;

SEGMENT_NAME                        TOTAL_SPACE
----------------------------------- -----------
DEPT                                      65536
DUMMY                                     65536
EMP                                   713031680
EMP_IDX                               478150656
SALGRADE                                  65536

Elapsed: 00:00:00.25
SQL> 
SQL> --
SQL> -- Compress for QUERY LOW
SQL> --
SQL> -- Note elapsed time
SQL> --
SQL> alter table emp move compress for query low;

Table altered.

Elapsed: 00:00:16.16
SQL> 
SQL> alter index emp_idx rebuild;

Index altered.

Elapsed: 00:00:43.08
SQL> 
SQL> --
SQL> -- These figures are the same as those generated
SQL> -- AFTER the HCC compressed data was updated the first time
SQL> --
SQL> select table_name, compression, compress_for
  2  from user_tables;

TABLE_NAME                     COMPRESS COMPRESS_FOR
------------------------------ -------- ------------
DEPT                           DISABLED
BONUS                          DISABLED
SALGRADE                       DISABLED
DUMMY                          DISABLED
EMP                            ENABLED  QUERY LOW

Elapsed: 00:00:00.02
SQL> 
SQL> select segment_name, sum(bytes) total_space
  2  from user_segments
  3  group by segment_name;

SEGMENT_NAME                        TOTAL_SPACE
----------------------------------- -----------
DEPT                                      65536
DUMMY                                     65536
EMP                                    14680064
EMP_IDX                               260046848
SALGRADE                                  65536

Elapsed: 00:00:00.02
SQL>

Archive

HCC 的 Archive 压缩类型是目标是节省更多的空间,因此它会认为被压缩的数据是只读的和偶尔使用的数据,当然这些被压缩的表是无法更新的。我们将使用 ARCHIVE HIGH 来压缩我们的 EMP 表来看看空间节省情况:

SQL> --
SQL> -- Current storage for the EMP table
SQL> -- (this is simply a test table for this example)
SQL> --
SQL> select segment_name, sum(bytes) total_space
  2  from user_segments
  3  group by segment_name;

SEGMENT_NAME                        TOTAL_SPACE
----------------------------------- -----------
DEPT                                      65536
DUMMY                                     65536
EMP                                   713031680
EMP_IDX                               478150656
SALGRADE                                  65536

Elapsed: 00:00:00.02
SQL> 
SQL> --
SQL> -- Compress the table for archive high
SQL> --
SQL> -- Note elapsed time to compress
SQL> --
SQL> alter table emp move compress for archive high;

Table altered.

Elapsed: 00:00:38.55
SQL> 
SQL> --
SQL> -- Index is now invalid
SQL> --
SQL> -- Must rebuild to make it usable
SQL> --
SQL> -- Note elapsed time
SQL> --
SQL> alter index emp_idx rebuild;

Index altered.

Elapsed: 00:00:39.45
SQL> 
SQL> --
SQL> -- Current compression type, storage for table/index
SQL> -- initially after compression is enabled
SQL> --
SQL> select table_name, compression, compress_for
  2  from user_tables;

TABLE_NAME                     COMPRESS COMPRESS_FOR
------------------------------ -------- ------------
DEPT                           DISABLED
BONUS                          DISABLED
SALGRADE                       DISABLED
DUMMY                          DISABLED
EMP                            ENABLED  ARCHIVE HIGH

Elapsed: 00:00:00.02
SQL> 
SQL> select segment_name, sum(bytes) total_space
  2  from user_segments
  3  group by segment_name;

SEGMENT_NAME                        TOTAL_SPACE
----------------------------------- -----------
DEPT                                      65536
DUMMY                                     65536
EMP                                     4194304
EMP_IDX                               260046848
SALGRADE                                  65536

Elapsed: 00:00:00.01
SQL>

节省了大量的空间,表从原来的 680MB 压缩到 4MB,压缩比达到 99.41%。使用 ARCHIVE LOW 来压缩仍然能得到很好的压缩结果:

SQL> --
SQL> -- Initial storage
SQL> --
SQL> select segment_name, sum(bytes) total_space
  2  from user_segments
  3  group by segment_name;

SEGMENT_NAME                        TOTAL_SPACE
----------------------------------- -----------
DEPT                                      65536
DUMMY                                     65536
EMP                                   713031680
EMP_IDX                               478150656
SALGRADE                                  65536

Elapsed: 00:00:01.31
SQL> 
SQL> --
SQL> -- Compress for ARCHIVE LOW
SQL> --
SQL> -- Note elapsed time
SQL> --
SQL> alter table emp move compress for archive low;

Table altered.

Elapsed: 00:00:34.16
SQL> 
SQL> alter index emp_idx rebuild;

Index altered.

Elapsed: 00:00:48.44
SQL> 
SQL> --
SQL> -- These figures are the same as those generated
SQL> -- AFTER the HCC compressed data was updated the first time
SQL> --
SQL> select table_name, compression, compress_for
  2  from user_tables;

TABLE_NAME                     COMPRESS COMPRESS_FOR
------------------------------ -------- ------------
DEPT                           DISABLED
BONUS                          DISABLED
SALGRADE                       DISABLED
DUMMY                          DISABLED
EMP                            ENABLED  ARCHIVE LOW

Elapsed: 00:00:00.03
SQL> 
SQL> select segment_name, sum(bytes) total_space
  2  from user_segments
  3  group by segment_name;

SEGMENT_NAME                        TOTAL_SPACE
----------------------------------- -----------
DEPT                                      65536
DUMMY                                     65536
EMP                                     8388608
EMP_IDX                               260046848
SALGRADE                                  65536

Elapsed: 00:00:00.02
SQL>

使用 ARCHIVE LOW 压缩后表的大小是 使用 ARCHIVE HIGH 压缩的两倍大,但是任然有 98.82% 的压缩比。这与 QUERY HIGH 的压缩情况相当。

在这些压缩方式上更新数据引入了一些有趣的结果;表会默默的将压缩类型转换到 OLTP (尽管数据目录仍然显示原先的压缩类型)并且会消耗更多的空间,虽然更新前他们并没有消耗那么多空间。OLTP 压缩支持自动 re-compression 方式,我称之为 "批处理模式(batch mode)" -- 块填充到 PCTUSED 会限制他们的压缩,需要创建更多空间来存放未压缩数据。这会一直持续到没有更多的数据可以放入块。这使得块处于混合状态中,一些被压缩,一些没有,因此更 新后的表大小不会在比初始化时小。

HCC 适合所有情况吗?不是,它不是为了适合所有情况。假设你认为你的表不会频繁更新而你觉得必须使用 HCC Query 进行压缩(它原来是数据仓库[Data Warehouse]应用),回忆一下上面说到的情况,当更新表以后表会默默的将压缩类型转换为 OLTP 压缩类型。HCC Archive 压缩应该针对归档(archived)数据进行,数据不会被更新并且你必须保存他们但希望尽可能少的占用空间。

HCC 拥有非常棒的压缩效率,但是对于一个频繁更新的业务数据库 OLTP 将是你首先要选择的压缩方式。

本文链接:http://www.4byte.cn/learning/37775/zai-oracle-shu-ju-ku-yun-fu-wu-qi-exadata-shang-shi-xian-hun-he-lie-shi-ya-suo-hybrid-columnar-compression.html