DB2 工作负载
磁盘 I/O 常常是影响响应时间的最大因素,但是通过查看 GETPAGE (GP) 请求,更容易理解底层的性能问题。当监控 DB2 活动和分析报告时,GETPAGE 的数量也许是 DB2 总体工作负载的最好的指示器。
某个安装环境下的很多 DB2 工作都可以无异议地归为以下几类:
事务: 事务是在事务管理器(例如 CICS 和 IMS/TM)控制下运行的程序。其中的 SQL 通常比较简单,但是事务量比较重。事务必须为用户提供极好的响应时间,这样应用程序才不致于要长时间地等待它们所需的资源。通常,第一个调用事务的用户将承受读取索引和数据页的成本。随后的用户则常常可以发现有些资源已经在缓冲池中。
查询: 查询也是程序,常常在需要决策支持时执行它。其中的 SQL 可能非常复杂,但是工作量常常远不及事务。查询的用户常常要等上数分钟甚至数小时,这取决于为了产生用户所请求的结果集,需要对多少数据进行搜索。查询常常要引起对整个表的扫描,而对结果排序是这种类型的工作负载的另一种常见特征。
批处理和实用程序: 批处理和实用程序通常处理大量的数据,并且常常以一种连续的方式处理数据。这些程序在给定的 窗口中完成它们的处理,这一点很重要。批处理和实用程序往往是各种系统资源的消费大户,一旦它们挤在一起,常常会使工作负载逐步上升。
规范化
规范化是分析应用程序所需的数据实体,然后将这些数据实体转化成一组设计良好的结构的一个格式化的过程。逻辑数据模型的一般设计目标是正确性、一致性、非冗余和简单性。而且,关系理论的信条也要求数据库要经过 规范化。
有一些按照连续编号排列的规则(也叫 范式(form))可以用来很详细地定义规范化数据。大多数专家都会建议设计者尽量遵从前三条规则,由此得到的数据就可以说是符合 第三范式。
而将一个表 反规范化(de-normalize)的意思是,违反该表之前遵从的一种或多种范式,从而修改规范化的设计。这种反标准化的过程常常是由于性能的原因而进行的。在大多数以关系数据库为主题的书籍当中,都可以找到关于规范化的更详细的信息。
DB2 表空间类型
在一个定义好的 DB2 数据库中,实际的表必须在称作 表空间(table space)的 DB2 对象中创建。用户可以在 DB2 中定义 4 种不同的表空间:
简单表空间:简单表空间可以包含一个以上的 DB2 表。这种表空间由页构成,每个页可以包含该表空间中定义的任何表中的行。
分段表空间: 分段表空间可以包含一个以上的 DB2 表。这种表空间由页组构成,页组被称作 段(segment)。每个段只能包含该表空间中定义的一个表中的行。
分区表空间:分区表空间只能包含一个表。根据 分区(partitioning)索引的键范围,这种表空间被分成数个分区。每个分区都被看作一个独立的实体,允许 SQL 和 DB2 实用程序对其进行并发处理。
LOB 表空间: LOB 表空间只用于 LOB(大型对象)数据。LOB 包括三种数据类型:BLOB(二进制大型对象)、CLOB(字符大型对象)和 DBCLOB(双字节字符大型对象)。
表空间与表设计方面的考虑 记录大小和页宽 固定长度的记录要优于可变长度的记录,因为 DB2 代码专门为处理固定长度的记录进行优化。如果记录是固定长度的,那么就无需将其从存储它的初始页面转移到其他地方。而对于可变长度的记录,其长度可能会变得不再适合初始页,因此必须将其转移到其他页。之后,每当需要访问该记录时,就必须发生额外的页引用。DB2 UDB V8 中的一种新特性允许在需要的时候修改(ALTER)某一列的宽度,这样一来,即使您不能确定将来数据长度的增长情况,也不再需要创建可变长度的记录。
一个页中所能存放的记录的数目也是值得考虑的一个方面。DB2 为页宽提供了很多选项(4 KB、8 KB、16 KB 和 32 KB)。一开始的时候,可以选择默认选项(4 KB),如果行的长度很小,或者对数据的访问基本上是随机的,则更应该选择这一选项。不过,在有些情况下,则需要考虑使用更大的页宽。如果一个表中各行的长度要大于 4 KB,那么就需要使用更大的页宽,因为 DB2 不支持 跨页(spanned)记录。
还有一些情况下,对于一条固定长度的记录,其总长度可能刚好比 4 KB 的一半大一点点,这时一个页只能容纳一条记录。对于刚好比页宽的 1/3、1/4 大一点点的记录,情形也是类似的。这种设计不仅浪费 DASD 空间,而且,对于很多 DB2 操作,还需要消耗更多的资源。因此,对于这一类的记录,应该考虑使用更大的页宽,这样浪费的空间相对要少一些。
其他可能的页宽是 8 KB、16 KB 和 32 KB。页宽不是在 CREATE TABLE 语句中直接指定的。相反,表的页宽是由相应的缓冲池的页宽来确定的,这个缓冲池也就是为包含该表的表空间所指定的缓冲池。要了解更多细节,请参考 DB2 SQL Reference手册中的 CREATE TABLESPACE 语句。
反规范化方面的考虑 逻辑数据模型是数据的 理想蓝图。物理数据模型才是对数据的 现实的实现。规范化只关注数据的意义,而没有考虑对于访问数据的应用程序的性能需求。完全规范化的数据库设计在性能方面要受到质疑。
这种性能问题的最常见的例子是 连接(join)操作。通常,规范化过程最终将相关的信息放入不同的表中。于是应用程序需要从多个这样的表中访问数据。关系数据库为 SQL 语句提供了从一个以上的表中访问信息的能力,这是通过 连接多个表来完成的。连接操作可能要消耗大量的资源和时间,这取决于表的数量以及这些表各自的长度。
像 I/T 中的很多事情一样, 这里也可以考虑一种权衡的方法。对于具有经常被请求的列的多个表,一种是复制其中的数据,一种是执行表连接,两者谁的成本更高呢?在逻辑数据库设计过程中,您可以毫无保留地规范化数据模型,然后再加入一定程度的反规范化,作为潜在的性能调优的一种选择。如果您确实打算反规范化,那么一定要为此制作完整文档:较详细地描述您所采取的反规范化步骤背后的原因。
设计大型的表 访问非常大的 DB2 表时,相应地要消耗很多的资源:
CPU、
内存 和 I/O。在设计大型表的时候,为了提高性能,用户可以做的最重要的两件事是:
1、实现分区。
2、创建有用的索引。
下面将更详细地讨论这两个话题。
使用分段的或分区的表空间 如果数据包括 LOB,那么用户就必须创建 LOB 表空间。对于非 LOB 数据,一般需要在分区表空间和分段表空间之间进行选择,这很大程度上取决于要存储的数据量,在一定长度上也取决于相关应用程序所需的数据访问类型。简单表空间已经很少被推荐了。
下面列出了分段表空间相对于简单表空间的一些性能优势:
对于包含多个表的表空间,当 DB2 取得用于某一个表的锁时,这个锁不会影响对其他表的段的访问。
当 DB2 扫描一个表时,只是访问与那个表相关的段。而且,空段中的页不会被提取。
如果一个表被删除,在执行 COMMIT 之际,它的段就立即可以为其他表所用,而不需要执行 REORG 实用程序。
如果一个表中的所有行都被删除(即 mass delete),则在执行 COMMIT 之际,该表所有的段就立即可以为其他表所用,而不需要执行 REORG 实用程序。
mass delete 执行起来要高效得多,并且要写的日志信息也更少一些。
COPY 实用程序不会复制那些由 mass delete 操作或删除(DROP)一个表所造成的空页。
当表达到一定大小时,通过实现分区表空间可以提高易管理性和性能。如果预见到这样的增长,那么明智的做法是,在设计和创建表空间时将其定义为分区的。下面列出了分区表空间可以提供的一些潜在的优势:
并行性:您可以使用 DB2 UDB 目前所使用的三种并行方式。查询并行(多条 I/O 路径)是在 DB2 V3 中引入的。Sysplex 查询并行(一个 DB2 数据共享组中的多用户和多任务)是在 DB2 UDB V5 中引入的。到现在,DB2 已得到极大的发展,并大大地增强了那些处理分区表空间的 DB2 应用程序的并行处理能力。通过增加一定的 CPU 时间,可以大大减少这些查询所需的时间。
对部分数据进行操作: 分区表空间允许 DB2 实用程序一次处理一个分区的数据,这样其他任务或应用程序就可以并发地对其他分区进行访问。按照类似的方式,您可以将 mass UPDATE、DELETE 或 INSERT 操作拆成多个不同的任务。除了增加可用性以外,这种技术还可以为减少完成这种 DB2 工作所需的时间提供潜力。
对频繁访问的数据有更快的访问速度: 如果分区索引可以将访问更频繁的行与表中其他的行分开来,那么就可以将这些数据放入到它们专用的分区中,并使用更高速的 DASD 设备。
通常,表越大,就越有理由将其创建为分区的表。但有时候为较小的表创建分区表空间也很有利。当将 查找(lookup)表与其他较大的分区的表相连接时,通过将查找表也进行分区,可以最大化并行度。
如果在连接谓词中使用分区键(partitioning key),最后还有一点考虑需要顾及。需要按分区键进行连接的表应该有相同数量的分区,并且应该在相同的值上 断开。