此文章主要向大家讲述的是DB2 V9.7 索引压缩新特性的正确使用,我们大家都知道DB2 V9.1 数据库其提出了行压缩技术,在实际应用中当系统中数据量很大,IO 需求超过了磁盘系统提供的容量(即 IO 成为系统的瓶颈)时,行压缩技术能够有效的减少读写磁盘的次数。
DB2 9.7 更进一步提出了索引压缩技术,减少索引磁盘空间的占用,减少读取索引时的 IO 次数从而提高了性能。
DB2 压缩不仅有助于减少在线数据库存储区需求,还有助于减少在备份和灾难恢复时所需的存储器数量。此外,由于在备份与恢复过程中涉及到的数据量变小了,所以备份与恢复操作所花的时间也就变短了。所有这些因素都在无形中节约了 IT 成本。
简介
数据库中占用物理存储空间的对象主要是表和索引,这两类对象的大小直接影响着磁盘空间的占用,同时也决定着数据库的性能。当前数据库系统中,随着时间的推移表会越来越大,对应着索引也会越来越大,这也是我们的系统越来越慢的原因。 DB2 V9.1 中提出了全新的行深度压缩(deep compression)的技术,以应对这种挑战。
尽管深度压缩的主要目的是节省存储空间,但是使用它也可以大大节省磁盘 I/O 并提高缓冲池命中率。因而可以提高性能,并无需成本——数据压缩和解压缩需要占用额外的 CPU 周期。深度压缩的存储节省和性能影响与数据、数据库本身的设计、数据库调优程度以及应用程序负载有关。
在 DB2 V9.7,IBM 在行压缩的基础上提出了索引压缩,其目标与行压缩一样,都是为减少磁盘空间的占用,这同时适用于大型 OLTP 和数据仓库环境。 DB2 V9.7 采用多种压缩算法对索引进行自动压缩。本文不会对具体的压缩算法进行讨论,而是将重点放在索引压缩的应用场景上,即如何启动索引压缩、什么数据分布适合索引压缩,什么数据不适合索引压缩。
如何启用索引压缩
在缺省情况下,当对表启动压缩后,索引压缩也处在启动状态。对于未压缩的表索引压缩处于禁用状态,我们可以使用 CREATE INDEX 语句的 COMPRESS YES 选项可以更改此缺省行为。创建索引之后,我们还可以使用 ALTER INDEX 语句来启用或禁用索引压缩功能;然后,必须执行 INDEX REORG 以重建索引。
启用索引压缩功能后,DB2 将根据数据库管理器所选择的压缩算法对索引页在磁盘上和内存中的格式进行修改,以便最大程度地减少存储空间耗用量。根据所创建索引类型以及索引所包含数据的不同,DB2 实现的压缩程度也会有所变化。例如,通过存储重复键的记录标识(RID)的缩写格式,数据库管理器可以对包含大量重复键的索引进行压缩。
在索引键前缀的公共程度很高的索引中,数据库管理器可以根据索引键前缀的相似性来进行压缩。
索引压缩是使用 CPU 的空闲周期或者是 CPU 在等待 IO 时的周期对索引数据进行压缩、解压缩的。因此在带来 IO 成本节约的同时,索引压缩技术增加了系统的 CPU 负担,如果我们的系统不受到 CPU 的约束,我们在对数据进行 Select、Insert、Update 时都能感觉到索引压缩技术带来的性能提升。
如果我们的系统本身 CPU 就已经比较繁忙了,再启用索引压缩可能会带来一些负面影响。
清单 1. 创建表时指定表压缩
- db2 "create table t1 (col1 int) compress yes"
- db2 "create index idx_col1 on t1(col1) "
- db2 "select substr(INDNAME,1,18),substr(TABNAME,1,18),COMPRESSION,PCTPAGESSAVED
- from syscat.indexes where tabname='T1'"
- 1 2
- COMPRESSION PCTPAGESSAVED
- IDX_COL1 T1 Y -1
上面的语句中首先创建了一张表 T1,并对该表启动行压缩。在创建索引 idx_col1 时,由于基表启动了压缩,索引压缩也被自动启动。上述代码的第三句就是验证索引 idx_col1 确实启动了压缩,而由于未收集统计信息因此当前压缩比例是 -1 。当我们向表中 Insert 或者 Update 数据时,索引自动被压缩维护到物理存储上。
如果我们在创建表时未指定表进行压缩,那么此表上创建的索引默认情况下是不压缩的,如果期望对索引进行压缩需要进行以下步骤。
- db2 "create table t2 (col1 int)
- db2 "create index idx_col2 on t2(col1) "
- db2 "select substr(INDNAME,1,18),substr(TABNAME,1,18),COMPRESSION,PCTPAGESSAVED
- from syscat.indexes where tabname='T2'"
- 1 2 COMPRESSION PCTPAGESSAVED
- IDX_COL2 T2 N
- -1
- db2 "alter index idx_col2 compress yes"
- db2 "select substr(INDNAME,1,18),substr(TABNAME,1,18),COMPRESSION,PCTPAGESSAVED
- from syscat.indexes where tabname='T2'"
- 1 2 COMPRESSION PCTPAGESSAVED
- IDX_COL2 T2 Y -1
上面语句中开始创建表时未指定表进行压缩,后继创建的索引默认情况下不压缩。如果希望索引启动压缩功能,则可以使用 alter 语句进行更改。
注意,即使我们更改将索引更改为压缩后,后来插入的数据还是未压缩的,直到我们使用 reorg 语句重组索引。 DB2 考虑中间更改索引的压缩属性,需要对更改前、更改后的插入的数据保持一致性,不可能在索引中同时存在非压缩、压缩数据。
我们对上面的 IDX_COL2 执行以下脚本,插入 1 万行数据:
- INSERT INTO t2 (col1)
- WITH TEMP (COUNTER, col1) AS
- (
- VALUES (0, INT(RAND() * 1000))
- UNION ALL
- SELECT
- (COUNTER + 1), INT(RAND() * 1000)
- FROM
- TEMP
- WHERE
- (COUNTER + 1) < 10000
- )
- SELECT
- col1
- FROM
- TEMP
- ;
然后我们收集表和索引的统计信息。
- db2 "runstats on table db2admin.t2 and indexes all"
- db2 "select substr(INDNAME,1,18),substr(TABNAME,1,18),COMPRESSION,PCTPAGESSAVED
- from syscat.indexes where tabname='T2'"
- 1 2 COMPRESSION PCTPAGESSAVED
- IDX_COL2 T2 Y 0
大家会发现压缩率为 0,这是因为我们还没有对索引进行 reorg 。当然,除了上面 Select 语句我们也可以使用 REORGCHK 工具检查是否需要对索引进行 Reorg 。
- db2 "reorg indexes all for table db2admin.t2"
- db2 "runstats on table db2admin.t2 and indexes all"
- db2 "select substr(INDNAME,1,18),substr(TABNAME,1,18),COMPRESSION,PCTPAGESSA
- VED from syscat.indexes where tabname='T2'"
- 1 2 COMPRESSION PCTPAGESSAVED
- IDX_COL2 T2 Y 40
以上的相关内容就是对DB2 V9.7 索引压缩新特性的使用的介绍,望你能有所收获。
【编辑推荐】