DB2 9:行压缩与大型 RID

在 DB2 9 中进行行压缩时考虑大型 RID

本文描述大型行 ID(RID)对 DB2 for Linux, UNIX, and Windows 中行压缩的影响。大型 RID 与行压缩特性是在 DB2 9 中引入的。行压缩可以显著减少平均行大小,但是当不使用大型 RID 的时候,就会受到常规表空间每页 255 行的限制。通过考察 TPCH 数据库的 ORDERS 表的一个简单的测试用例,看看使用大型 RID 如何绕过每页行数限制,每页行数对于最大化 DB2 for Linux, UNIX, and Windows 中行压缩的优点是一个重要的因素。

Peter Schurr (peter.schurr@de.ibm.com), DB2 IT 专家, IBM

Peter Schurr 在 IBM 德国的 IBM Software Group 担任 IT 服务专家。他的专业领域是 DB2 for Linux, UNIX, and Windows 管理和应用程序开发。他有 8 年的 DB2 工作经验,并且是 IBM 认证的高级 DBA 和 IBM 认证的应用程序开发人员。Peter 特别擅长于性能调优、复制、联邦数据库和数据建模。



2007 年 10 月 30 日

大型 RID

在 DB2 Version 8 中,表和表空间大小都是有限制的,如表 1 所示。表和表空间大小限制取决于页大小。用作指针的字节数是 3 个字节。因此,只有 2 的 24 次方个单位可供使用。由此可得到 16,777,216 个页面。 由于页内的页槽号占 1 个字节,因此可寻址的行数为 255 乘以 16,777,216。取决于页大小,存在以下限制:

表 1. DB2 V8 中取决于页大小的表空间限制
页数页大小表/表空间限制
16,777,2164 K64 GB
16,777,2168 K128 GB
16,777,21616 K256 GB
16,777,21632 K512 GB

在 DB2 9 中,这些限制被放宽了。用于页寻址的字节数增加到 4 个字节,页槽号现在用 2 个字节表示。 表 2 显示了 DB2 9 中的表和表空间限制。

表 2. DB2 9 中取决于页大小的表空间限制
页数页大小表/表空间限制
536,870,9124 K2 TB
536,870,9128 K4 TB
536,870,91216 K8 TB
536,870,91232 K16 TB

大型 RID 只在 DB2 9 中的大型表空间中受支持。这不同于 DB2 Version 8,在 DB2 Version 8 中,大型表空间只是为 LOB 和 LONG 数据类型设计的。但是当从 DB2 8 迁移至 DB2 9 时要记住,常规表空间不会被转换成大型表空间。在迁移计划中,要考虑到可能需要将常规表空间转变为大型表空间。

行压缩

DB2 中的行压缩特性可用于在表一级节省存储空间。其优点是节省容器空间,缩小备份镜像(从而减少备份时间),以及减少缓冲池中的页活动。可以为单个表激活行压缩。 进行行压缩时,会创建一个包含可重用模式的字典。对于这些模式,会存储一个指针。通过使用 DB2 INSPECT 命令可以估计每个表的压缩率。

压缩与大型 RID

行压缩可以减少平均行大小。当使用常规表空间时(假设是从 DB2 Version 8 迁移至 DB2 9,常规表空间将保留),限制仍然固定为每页 255 行。虽然使用行压缩可以减少平均行大小,但是仍然会受到每页行数的限制,并且会浪费表空间容器上的存储空间。

数据库 TPCH 中表 ORDERS 上的例子

下面的例子使用 TPCH 数据库的 ORDER 表(大小总共为 1 GB)以展示在使用行压缩之后 RID 数量的影响。这里使用一个平均行大小较小的表。因此,这个表已经被修改,更改了初始的最大行大小。列 O_COMMENT 被裁剪为长度为 20 个字符(而不是 79 个字符)。表空间使用 16 K 的页大小来存储表 ORDERS。使用这个页大小时,很好解释大型 RID 的影响。

下面的例子中的主要步骤有:

  1. 在 DB2 Version 8 中,在一个常规表空间中创建一个表 ORDERS,检查页数、平均行大小和每页行数。
  2. 将实例和数据库迁移至 DB2 9。
  3. 在 DB2 9 中创建一个新的大型表空间。
  4. 在新的大型表空间中创建和 ORDER 表类似的 ORDERS2 表。
  5. 压缩表 ORDERS 和 ORDERS2,并分别在这两个表上运行 reorg。
  6. 现在可以比较这两个表的页数、平均行大小和每页行数。可以看到常规表空间与大型表空间之间存在不同之处。

修改表设计

例子 1 显示了表 ORDERS 的结构。其中列 O_COMMENT 已经被修改。

例子 1. 表 ORDERS 的 DDL
db2inst1@mstar:~/test/compr_lrid> db2 describe table orders

Column                         Type      Type
name                           schema    name               Length   Scale Nulls
------------------------------ --------- ------------------ -------- ----- ------
O_ORDERKEY                     SYSIBM    INTEGER                   4     0 No
O_CUSTKEY                      SYSIBM    INTEGER                   4     0 No
O_ORDERSTATUS                  SYSIBM    CHARACTER                 1     0 No
O_TOTALPRICE                   SYSIBM    DECIMAL                  15     2 No
O_ORDERDATE                    SYSIBM    DATE                      4     0 No
O_ORDERPRIORITY                SYSIBM    CHARACTER                15     0 No
O_CLERK                        SYSIBM    CHARACTER                15     0 No
O_SHIPPRIORITY                 SYSIBM    INTEGER                   4     0 No
O_COMMENT                      SYSIBM    VARCHAR                  20     0 No

  9 record(s) selected.

db2inst1@mstar:~/test/compr_lrid>

平均行大小(即查询中的 AVG_ROW_SIZE 列)从原表的 107 字节减少为 79 字节,见例子 2。列 ROWS_PER_PAGE 是通过将行数(CARD)除以页数(NPAGES)得到的。

例子 2. 常规表空间中的表 ORDERS
db2inst1@mstar:~/test/compr_lrid> db2 -tvf ars.sql
SELECT SUBSTR(a.tabname,1,10) AS table, b.npages , 
CASE WHEN (b.NPAGES  > 0) THEN (b.CARD / b.NPAGES) ELSE -1 END AS ROWS_PER_PAGE, 
SUM(AVGCOLLEN) AVG_ROW_SIZE 
FROM SYSCAT.COLUMNS a, SYSCAT.TABLES b, SYSCAT.TABLESPACES c 
WHERE a.tabschema = b.tabschema AND a.tabname = b.tabname AND b.tbspaceid = c.tbspaceid 
AND a.tabname = 'ORDERS' 
GROUP BY a.tabschema, a.tabname, pagesize, card, npages
TABLE      NPAGES               ROWS_PER_PAGE        AVG_ROW_SIZE
---------- -------------------- -------------------- ------------
ORDERS     8198                  182                           79

  1 record(s) selected.


db2inst1@mstar:~/test/compr_lrid>

在 DB2 Version 8 中的常规表空间中,在无压缩模式下,每页存储 182 行。总共有 8198 个页。这接近于每页 255 行的限制,所以 16 K 的页大小是个很好的选择。在将实例和数据库迁移至 DB2 9 之后,必须刷新统计数字。一个新的页大小为 16 K 的大型表空间 ltb16K 将被创建,在新的大型表空间中将创建与表 ORDER 类似的一个新表 ORDERS2。 TPCH 数据库中没有使用索引或约束。因此,表的创建非常简单。数据将由游标装载,如例子 3 所示。

创建大型表空间

例子 3. 创建表 ORDERS2
db2inst1@mstar:~/test/compr_lrid> ./cr_tbspace_ltb16k.sh
   Database Connection Information

 Database server        = DB2/LINUX 9.1.0
 SQL authorization ID   = DB2INST1
 Local database alias   = TPCH

DROP TABLESPACE ltb16K
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL0204N  "LTB16K" is an undefined name.  SQLSTATE=42704

CREATE LARGE TABLESPACE ltb16K PAGESIZE 16 K MANAGED BY DATABASE 
  USING ( FILE '/db2/db2inst1/TPCH/ltb16K.001' 20000 ) BUFFERPOOL bp16k
DB20000I  The SQL command completed successfully.

CREATE TABLE orders2 LIKE orders IN ltb16K
DB20000I  The SQL command completed successfully.

DB20000I  The SQL command completed successfully.
DECLARE c1 CURSOR FOR SELECT * FROM orders
DB20000I  The SQL command completed successfully.

LOAD FROM c1 OF CURSOR INSERT INTO orders2
SQL3501W  The table space(s) in which the table resides will not be placed in
backup pending state since forward recovery is disabled for the database.
SQL1193I  The utility is beginning to load data from the SQL statement "
SELECT * FROM orders".
SQL3500W  The utility is beginning the "LOAD" phase at time "2007-02-09
23.03.50.673543".
SQL3519W  Begin Load Consistency Point. Input record count = "0".
SQL3520W  Load Consistency Point was successful.
SQL3110N  The utility has completed processing.  "1500000" rows were read from
the input file.
SQL3519W  Begin Load Consistency Point. Input record count = "1500000".
SQL3520W  Load Consistency Point was successful.
SQL3515W  The utility has finished the "LOAD" phase at time "2007-02-09
23.04.17.263410".
Number of rows read         = 1500000
Number of rows skipped      = 0
Number of rows loaded       = 1500000
Number of rows rejected     = 0
Number of rows deleted      = 0
Number of rows committed    = 1500000
db2inst1@mstar:~/test/compr_lrid>

在 DB2 9 中的大型表空间中,在无压缩模式下,每页也是存储 182 行。平均行大小(79)与页数(8198)与常规表空间中的一样,如例子 4 所示。

例子 4. 大型表空间中 ORDERS2 表的数字
db2inst1@mstar:~/test/compr_lrid> db2 -tvf ars.orders2.sql
SELECT SUBSTR(a.tabname,1,10) AS table, PAGESIZE, b.CARD, b.npages , 
CASE WHEN (b.NPAGES  > 0) THEN (b.CARD / b.NPAGES) ELSE -1 END AS ROWS_PER_PAGE, 
SUM(AVGCOLLEN) AVG_ROW_SIZE FROM SYSCAT.COLUMNS a, SYSCAT.TABLES b, SYSCAT.TABLESPACES c 
WHERE a.tabschema = b.tabschema AND a.tabname = b.tabname AND b.tbspaceid = c.tbspaceid 
AND a.tabname = 'ORDERS2' 
GROUP BY a.tabschema, a.tabname, pagesize, card, npages
TABLE      NPAGES               ROWS_PER_PAGE        AVG_ROW_SIZE
---------- -------------------- -------------------- ------------
ORDERS2                    8198                  182           79

  1 record(s) selected.
db2inst1@mstar:~/test/compr_lrid>

DB2 9 中的编目包含一个名为 AVGROWSIZE 的新列,这个列显示一个表中压缩行和无压缩行的平均大小(单位为字节)。例子 5 分别针对表 ORDERS 和 ORDERS2 检索这个列。这两个表的平均行大小均为 89 字节。这个值与计算出的 79 字节略微有些差别 - 计算值是通过计算所有列的 AVGCOLLEN 得到的。

例子 5. 检索无压缩模式下的 AVGROWSIZE
db2inst1@mstar:~/test/compr_lrid> db2 "select AVGROWSIZE 
from syscat.tables where tabname = 'ORDERS2' "

AVGROWSIZE
----------
        89

  1 record(s) selected.

db2inst1@mstar:~/test/compr_lrid>
db2inst1@mstar:~/test/compr_lrid> db2 "select AVGROWSIZE 
from syscat.tables where tabname = 'ORDERS' "

AVGROWSIZE
----------
        89

  1 record(s) selected.

db2inst1@mstar:~/test/compr_lrid>

压缩表

现在这两个表都已经被压缩,如例子 6 所示。

注意:表的重组是必需的,ALTER TABLE 语句只是更新编目的内容。

例子 6. 压缩表
db2inst1@mstar:~/test/compr_lrid> db2 "alter table db2inst1.orders compress yes"
DB20000I  The SQL command completed successfully.
db2inst1@mstar:~/test/compr_lrid>
db2inst1@mstar:~/test/compr_lrid> db2 "alter table db2inst1.orders2 compress yes"
DB20000I  The SQL command completed successfully.
db2inst1@mstar:~/test/compr_lrid>
db2inst1@mstar:~/test/compr_lrid> time db2 -v "reorg table db2inst1.ORDERS 
 resetdictionary"
reorg table  db2inst1.ORDERS resetdictionary
DB20000I  The REORG command completed successfully.

real  0m58.335s
user  0m0.018s
sys 0m0.029s
db2inst1@mstar:~/test/compr_lrid>

db2inst1@mstar:~/test/compr_lrid> time db2 -v "reorg table  db2inst1.ORDERS2 
 resetdictionary"
reorg table  db2inst1.ORDERS2 resetdictionary
DB20000I  The REORG command completed successfully.

real  0m59.505s
user  0m0.020s
sys 0m0.028s
db2inst1@mstar:~/test/compr_lrid> db2 "reorgchk update statistics 
on table db2inst1.orders " > reorgchk.orders.compr.out

db2inst1@mstar:~/test/compr_lrid> db2 "reorgchk update statistics 
on table db2inst1.orders2 " > reorgchk.orders2.compr.out
db2inst1@mstar:~/test/compr_lrid>

在例子 7 中可以看到,常规表空间中的页数现在是 253,它仍然受每页 255 行的限制。但是,在大型表空间中,对于表 ORDERS2,每页可以有 427 行。因此,表 ORDERS2 使用的页数少于表 ORDERS 使用的页数。当压缩常规表空间中的表时,效果就显现出来了。在常规表空间中,仍然受每页 255 行的限制。为了避免这个限制,必须使用大型表空间,然后就可以在压缩之后每页存储更多的行。

例子 7. 压缩后的数字
db2inst1@mstar:~/test/compr_lrid> db2 -tvf ars.sql
SELECT SUBSTR(a.tabname,1,10) AS table, PAGESIZE, b.CARD, b.npages , 
CASE WHEN (b.NPAGES  > 0) THEN (b.CARD / b.NPAGES) ELSE -1 END AS ROWS_PER_PAGE, 
SUM(AVGCOLLEN) AVG_ROW_SIZE FROM SYSCAT.COLUMNS a, SYSCAT.TABLES b, SYSCAT.TABLESPACES c 
WHERE a.tabschema = b.tabschema AND a.tabname = b.tabname AND b.tbspaceid = c.tbspaceid 
AND a.tabname = 'ORDERS' GROUP BY a.tabschema, a.tabname, pagesize, card, npages
TABLE      NPAGES               ROWS_PER_PAGE        AVG_ROW_SIZE
---------- -------------------- -------------------- ------------
ORDERS                     5907                  253           79

  1 record(s) selected.

db2inst1@mstar:~/test/compr_lrid> db2 -tvf ars.orders2.sql
SELECT SUBSTR(a.tabname,1,10) AS table, PAGESIZE, b.CARD, b.npages , 
CASE WHEN (b.NPAGES  > 0) THEN (b.CARD / b.NPAGES) ELSE -1 END AS ROWS_PER_PAGE, 
SUM(AVGCOLLEN) AVG_ROW_SIZE FROM SYSCAT.COLUMNS a, SYSCAT.TABLES b, SYSCAT.TABLESPACES c 
WHERE a.tabschema = b.tabschema AND a.tabname = b.tabname AND b.tbspaceid = c.tbspaceid 
AND a.tabname = 'ORDERS2' GROUP BY a.tabschema, a.tabname, pagesize, card, npages
TABLE      NPAGES               ROWS_PER_PAGE        AVG_ROW_SIZE
---------- -------------------- -------------------- ------------
ORDERS2                    3512                  427           79

  1 record(s) selected.

db2inst1@mstar:~/test/compr_lrid>

如例子 8 所示,平均行大小(AVGROWSIZE)仍然相同。现在平均行大小是 38 字节。在不压缩的情况下这个值为 89 字节(见 例子 5)。

例子 8. 检索 AVGROWSIZE
db2inst1@mstar:~/test/compr_lrid>

db2inst1@mstar:~/test/compr_lrid> db2 "select AVGROWSIZE 
 from syscat.tables where tabname = 'ORDERS' "

AVGROWSIZE
----------
        38

  1 record(s) selected.
db2inst1@mstar:~/test/compr_lrid> db2 "select AVGROWSIZE 
 from syscat.tables where tabname = 'ORDERS2' "

AVGROWSIZE
----------
        38

  1 record(s) selected.
db2inst1@mstar:~/test/compr_lrid>

随着压缩特性的引入,编目中增加了一些新的列。特别是,列 PCTPAGESSAVED 显示压缩后节省的页数的比率。在这个例子中,在大型表空间中节省了 57% 的页,因为使用的页数从 8198 减至 3512。常规表空间需要更多的页。压缩后,常规表空间的页数可以从 8198 减至 5907,如例子 9 所示。使用大型表空间可以节省 40.5% 的页(从 5,907 减至 3,512)。

例子 9. 两个表各自节省的页
db2inst1@mstar:~/test/compr_lrid> db2 "select SUBSTR(tabname,1,20) AS table, npages, 
from syscat.tables where tabschema = 'DB2INST1' and tabname LIKE  'ORDERS%' "
TABLE                NPAGES               PCTPAGESSAVED
-------------------- -------------------- ------------------------ -------------
ORDERS                               5907                   27
ORDERS2                              3512                   57

  2 record(s) selected.
db2inst1@mstar:~/test/compr_lrid>

总结

表 3 对上述结果做了总结。使用大型表空间可以取得最大程度的节省。压缩之后,只需要 3,512 个页,而常规表空间仍然需要 5,907 个页。常规表空间与大型表空间之间的差距是 5,907 页 - 3,512 页,即前者浪费了 2,395 个页。

表 3. 页大小为 16 K 时每页行数比较
表空间模式CARDNPAGESAVGROWSIZEAVG ROWS PER PAGE
ORDERSREGULARNo compression1.500.0008.19889182
ORDERSREGULARCompressed1.500.0005.90738253
ORDERS2LARGENo compression1.500.0008.19889182
ORDERS2LARGECompressed1.500.0003.51228427

表 4 比较压缩后各表节省的空间。在表 ORDERS 中,压缩后节省了 28% 的页。而在表 ORDERS2 中,压缩后节省了 57% 的页。

表 4. 比较节省的空间
表空间PCTPAGESSAVED压缩前 NPAGES 压缩后 NPAGES SAVINGS
ORDERSREGULAR278,1985,90728
ORDERS2LARGE5708,1983,51257

当使用 32 K 的页大小时,常规表空间中的压缩失败,并收到警告 SQL2220W。在页大小为 32 K 的常规表空间中,最小记录大小为 127 字节(见表 6)。89 字节的平均行大小太低了。

表 6. 最小和最大记录大小
页大小常规表空间中最小记录大小常规表空间中最大记录大小大型表空间中最小记录大小大型表空间中最大记录大小
4 K1425112287
8 K3025312580
16 K62254121165
32 K127253122335

结束语:最佳实践

为了充分利用 DB2 9 中行压缩的优点,应遵循以下最佳实践:

  • 在迁移至 DB2 9 之后刷新统计数字(通过运行 RUNSTATSREORGCHK UPDATE STATISTICS)。
  • 使用 DB2 INSPECT 命令估计表上节省的空间,以决定哪些表值得压缩。
  • 行压缩之后,为了使压缩生效,应对表进行重组。
  • 从 DB2 Version 8 迁移至 DB2 9 时,要计划从常规表空间迁移至大型表空间。
  • 当迁移至大型表空间时,要同时考虑安排数据移动和数据重组。

参考资料

学习

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Information Management
ArticleID=265646
ArticleTitle=DB2 9:行压缩与大型 RID
publish-date=10302007