引言
这篇文章的目的是为了给IBM(r)商业伙伴提供一些重要的信息,这些信息是关于DB2通用数据库(UDB)在z/OS(r) 环境下(以下简称DB2)DB2(r)数据库性能方面的。本文试图将来自多方资源的材料进行整合,然后尽量有效地将信息展示出来。本文尽量避免在范围上过于宽泛,以及过于深入细节。
下面,我将要讨论那些最频繁影响DB2数据库性能的因素。我在这里并不涉及所有可能的条件和所有潜在的考虑,而是只局限于预期的范围之内。我希望这篇文章能够对DB2客户有一个总体的指导,从而使它们自己的环境中去获得DB2数据库的最适宜的性能。这篇文章将从如何在一个特定的安装中定制数据库的性能开始谈起。
这篇文章所涉及的范围是数据库设计性能。而DB2的性能包括的内容比这要多得多,除了数据库的设计之外,实际上还有很多其他的影响因素。例如,程序的编码逻辑,实际使用的SQL语句,都被划分在应用程序设计范围内了。影响DB2系统性能的因素包括了例如安装选项、缓冲池规模、DB2相关的地址空间的分配优先级,等。
本文的重点在于DB2数据库的设计。但是有些时候,这些影响性能的因素分类之间的界限有些模糊。例如,安装过程中对缓冲池的规模,选用缓冲池的数量进行的配置一般都被认为是系统性能因素。但是,当分配特定的表空间和那些缓冲池的索引的时候,就被认为是数据库设计所要考虑的了。
假设读者已经对z/OS环境下的DB2有了一些基本的了解。本文的前几页讨论了一些关于性能管理的基本概念和原则,以便于后面的理解。我的建议在本质上有些笼统,我总是避免过于纠缠技术细节或者语法等方面的问题。想要获得关于这些问题的详细信息,你可以查看IBM最近发布的有关安装在客户端的DB2的文档。
这篇文档主要着眼于z/OS V7环境下的DB2。虽然在z/OS V8下的DB2已经发布了,并且具有通用性,但是很可能还需要几个月的时间, IBM 的大多数客户才能够让他们的产品系统实现DB2 V8 NFM(新功能模式)。这里还有另一个需要考虑的问题:虽然每个新发布的DB2在正式通用之前,都会在IBM和客户环境中进行相当充分的测试,但是客户仍然很可能对基于前一版本的有关DB2的常见推荐和单凭经验的方法怀有更多的信心,而不是非常认同还没有发布,或者是没有获得普遍使用的新版本(由于验证结论的实际过程的时间长度和深度)。我会在文中提到一些可能会影响数据库设计性能的DB2 V8的新特性。
免责声明:本文包含的信息并没有提交给任何正式的IBM测试,并按”AS IS”原则提供。本信息的使用,或者是以上提到的任何技术的实现均由用户负责,且依靠用户的个人能力对其进行评估,并将其整合进入客户特定的操作环境中。其中的每一项都将在IBM特定的条件下获得精确的数值,这里不保证在其他地方会出现同样或者相似的结果。当用户尝试在各自的环境下采用上述技术时,需要自己承担风险。
性能原则和方法学
考虑性能的时机
考虑应用程序和数据库各自不同的性能特征的时间,是在对这些应用程序和数据库进行设计的初始阶段,即开发过程的一开始。对你的DB2应用程序和数据库所需要的资源进行合理评估,将会帮助用户在开发过程的早期对设计和实现做出适当的决定。如果你的应用程序访问数据库的性能直到后来才被说明,那么就要做必需的修改以获得足够的响应时间,并处理你的批处理窗口;这将会变得更加困难,并且消耗时间。
关注焦点
当设计性能的时候,将大部分的精力集中在重要的DB2数据和程序上是很明智的做法。对应用程序或者事务进行定义是这部分工作中的重点,以下一个或者多个特点是适用的:
它们表现了所有业务工作量中的大部分
它们有一个很关键的响应时间需求
它们包括了复杂的逻辑和/或数据访问需求
它们访问大量的数据
它们消耗大量的资源
它们直接与客户进行交互(通过网络、ATM等),与此相反,应用程序大多面向公司内部
数据库设计
数据库设计发生在以下两个阶段:
数据库逻辑设计
数据库物理设计
数据库的逻辑模型只是所有用户数据需求规格化的形式表现。这个模型通常是数据建模阶段的输出或者是最终结果。它很少在实际意义上被实现。更何况,在考虑如何在数据库管理系统中实际地组织和存储数据之前,它只是数据的一个理想化的视图。
当考虑到特定数据库对象的体系结构的时候,逻辑模型才会转化为物理模型。在这一设计阶段,才需要考虑到数据访问需求和性能因素的一些细节。在进行物理设计的过程中,两个关键的因素是表设计和索引设计。这两个问题将会在下面进行详细讨论。
DB2性能管理的方式
为了确保你的DB2应用程序有足够的性能,采取积极的态度总比消极应对有意义得多。在DB2数据库设计的早期阶段总结出性能因素是至关重要的。然后在项目中,努力尽早地确定满足你的服务级别协议(SLA)的性能“基线”的测量标准,这样你就可以在首次演示和应用程序变更的时候追踪性能特点及其发展趋势。不断地监测你的DB2系统和应用程序,以便在大多数的问题成形之前预见到它们。
传统意义上,许多客户都是直到应用程序开发项目的最后阶段才开始关心性能问题。但是这样的等待是毫无益处的。早在描述用户界面和处理逻辑的阶段就去思考数据库设计的性能特点,是比较有好处的。例如,在你的重要的DB2工作(见前面所述)中,创建最好的索引的一个基本的指导就是对SQL语句中的谓词的考虑。
即使是你开发出的最初设计是一个有效的设计,但是以下的若干修改仍然是必要的,例如对你的应用程序进行修改,或者数据库以卷的形式增长,或者是限制系统资源。如果现有的应用程序没有充分的运行,那么通常情况下你都会希望最好能够在现有的索引上面添加更多的列,或者在表上添加新的索引。不论改变表的设计,或者修改客户的需求,还是使表非标准化,通常情况下都不是好的选择。
理解DB2性能
单凭经验的方法
单凭经验的方法(又叫做ROT)在进行计划、监测,以及对DB2的性能进行优化时是很有用处的。ROT典型地基于以前的经验(例如,长时间的观测平均水平),或者是基于对比较复杂的公式进行简化。
记住下面这一点是很重要的,ROT对于粗略的估计有用,但是进行详细分析的时候就不行了。只是因为这些经验出现在某些文章中,就把它们作为性能的精确引证是很危险的。最好的情况下,它们是估计值;在最坏的情况下,它们对于你特定的DB2环境来说就是无效的。
ROT应该在你的环境中得到(或者是对其进行调整,使其适应你的环境)。它们应该与你的实际经验相联系,而不是被盲目接受,这样你才会对它们的值有信心。从那些在你的特殊环境之外得到的ROT开始也许会有些帮助。但是当你从你的DB2系统中收集、分析、记录了合适的数据之后,就需要对这些经验值进行校正或者修改。IBM的红皮书是一本有关ROT的值得阅读的资源,里面含有许多关于性能监测工具的推荐经验。
另一个要考虑的事项就是ROT需要持续一段时间。随着硬件技术的发展,软件编码的改进,系统的体系结构发生了变化,这使得ROT更加不可靠,甚至是完全错误的。随着时间的发展,使ROT发生改变的最大因素恐怕就是最新发布的DB2自身了。
DB2工作量
磁盘I/O通常是影响响应时间的最大因素,但是,通过查看GETPAGE (GP)需求可以更容易地看到潜在的性能问题。当监测DB2的活动并进行报告分析的时候,GETPAGE的数量很可能就是显示DB2整体工作情况的最好的指示器。
大部分的DB2安装工作可以分为以下几个较清晰的类别:
事务:这是运行在事务管理器控制之下的程序,例如CICS 和 IMS/TM。SQL通常比较简单,但是事务卷是很繁重的。事务必须为用户提供非常及时的响应时间,这样应用程序才不会被迫等待很长的时间以获得所需的资源。通常是第一个用户调用事务时才会产生读取索引和数据页的I/O开销。随后的用户可以在缓冲池中访问部分资源。
查询:这是通常情况下为决策支持运行的程序。其中的SQL也许十分复杂,但是卷通常要比事务的卷轻松许多。查询用户通常需要等待几分钟,甚至是几个小时,具体时间依赖于产生用户需要的结果集所查询的数据量。查询通常会调用针对整个表的扫描,并且对结果排序也是此类工作量的另一个常见特点。
批处理和实用工具集:批处理和实用工具集程序需要处理大量的数据,并且通常是以顺序的方式处理数据。在特定的窗口中结束处理对于这些程序来说是很重要的。多次使用位置正确的COMMIT(提交)语句是这些应用程序具有的一个很重要的特点。批处理和实用工具集通常需要消耗大量的各类资源,进行压缩的时候,通常可以逐步提高工作量。
标准化
标准化是应用程序进行数据实体分析的标准化过程,最终将把数据实体转换为一系列经过良好设计的结构体。通常,逻辑数据模型的设计目标是正确性、一致性、没有冗余和简单化。而且,关系理论原则也需要数据库进行标准化。
还有几条连续编号的规则,被称为范式,它可以相当详细地定义标准化数据。我在这里并不详细讨论这些规则。大多数的专家都会建议设计者们尽力遵循前三条的规则,因此这样的数据可被称为遵循第三范式。
对表进行非标准化的意思是,对一个先前遵守范式的表进行修改,使其违反一条或者多条范式规则。有时候,由于性能的原因,确实需要进行这个非标准化的过程。有关标准化的更进一步的详细信息,你可以在大多数的讲述关系数据库的书籍中找到。
DB2表空间的类型
在定义DB2数据库的时候,实际的表必须在被成为表空间的DB2对象中进行创建。用户可以在DB2中定义四种不同类型的表空间,如下所示:
单一:一个单一的表空间可以包含多于一个的DB2表。这个空间由多个页组成,每个页都可以包含若干行,它们可能是来自表空间中定义的任何表的数据行。
分段:分段表空间可以包含多于一个的DB2表。这个表空间由多组页组成,每组页被称为一个段。每个段包含来自表空间中定义的某一个表的若干行。
分区:分区表空间只可以包含一个表。这个空间根据分区索引的关键值范围被划分成多个区。每个分区都作为一个独立的实体对待,允许SQL和DB2实用工具集的并发处理。
LOB:LOB表空间只存储LOB(大对象)数据。LOB包括了3个数据类型:BLOB(二进制大对象)、CLOB(字符型大对象),以及DBCLOB(双字节字符型大对象)。
表空间和表设计考虑事项
记录尺寸和页尺寸
固定长度的记录比可变长度的记录要好,因为处理固定长度记录的DB2的代码经过了优化。如果记录是固定长度的,那么它就永远不需要从原来存储的页中被移动出来。然而,可变长度的记录可能增长到不再适合原来页的长度,因此它也就必须被移动到另一页。无论何时记录被顺序访问,都一定会出现一个额外的参考页。DB2 UDB V8中的一个新特性就是当你不确定未来的数据长度增长情况时,允许你根据需要改变列的尺寸,这样你就可以不再需要创建可变长度的记录。
每页中记录的数量也是需要考虑的内容。DB2提供了一些有关页尺寸的选项,例如4 KB, 8 KB, 16 KB和32 KB 。比较好的起点是选择默认的4KB,特别是当行的尺寸相对较小,或者是对数据的访问比较随机的情况下。然而,在一些情况下,也需要考虑较大的页尺寸。如果表中单个行的长度超过4KB,那么你就需要使用大一些的页尺寸,因为DB2不支持跨行的记录。
还有另一种情况是,当固定记录的总长度比二分之一的页(4KB)稍大一些的时候,一页中就只能放置一个记录。另外一种类似的情况是,固定记录的总长度略长于三分之一页、四分之一页,等。这样的设计不仅会浪费DASD空间,还会导致很多的DB2操作消耗更多的资源。因此,对于上面描述的记录而言,你需要考虑使用较大的页尺寸,这样就会相对地少浪费一些空间。
另外一些可能的页尺寸为8 KB, 16 KB和 32 KB。页的尺寸并不在创建表(CREATE TABLE)的语句中直接写明。相反,表中页的尺寸是由分配给包含这个表的表空间的缓冲池中的页尺寸决定的。要获得更详细的信息,你可以参考DB2 SQL 手册中有关创建表空间(CREATE TABLESPACE)语句的内容。
非标准化考虑事项
逻辑数据模型是数据的一个理想描述。物理数据模型则是数据在现实世界的实现。标准化只集中在数据的内涵上面,而不考虑可能访问数据的应用程序的性能需求。数据库设计的充分标准化会带来性能的挑战。
有关此类性能问题的一个非常常见的例子就是连接操作。通常情况下,标准化过程的结果是给各个独立的表赋予相互关联的信息。应用程序需要从这些表中访问数据。关系数据库提供了使用SQL语句来从多于一个的表中通过连接多个表去访问信息的能力。取决于表的数目和它们各自的尺寸,连接操作可能会消耗非常多的资源和时间。
因为在I/T中有如此多的事情需要考虑,于是出现了一个折中的想法。对那些包含被频繁访问列的多个表中的数据保存副本,与连接表的性能相比,成本高还是低呢?在逻辑数据库设计过程中,对你的数据模型尽量的执行标准化,之后再对其进行一定程度的非标准化,也许是进行潜在性能优化的一个选项。如果你决定进行非标准化了,要确保从头到尾地记录了文档:对某些细节的描述、执行非标准化步骤之后的推理,等。
设计较大的表
访问很大的DB2表需要消耗相当多的资源:CPU,内存,I/O。当设计大表的时候,用户需要做的两件最重要的事情就是:
实现分区
创建有用的索引
以上两个问题将在下面进行详细讨论。
使用分段或者分区表空间
如果数据中包含了LOB,那么用户就必须创建LOB表空间。对于非LOB的数据,通常的选择是分段或者分区表空间,具体选择哪一个在很大程序上取决于你要存储的数据量,同时还需要考虑相关应用程序需求的数据访问类型。不太推荐使用单一的表空间。
分段表空间比单一的表空间具有更多的性能优势,如下所示:
对于包含多于一个表的表空间,当DB2在一个表上获得锁定时,那个锁定不影响其他表分段的访问。
当DB2扫描一个表时,只访问与那个表相联系的分段。此外,空分段的页不会被取出。
如果一个表被清除了,不需要执行REORG实用工具集,它的分段就立即在COMMIT点上变成可再次使用的状态。
如果一个表中的所有行被删除了(被称为块删除),不需要执行REORG实用工具集,所有的分段都立即在COMMIT点上变成可再次使用的状态。
块删除操作起来更加有效,并且书写相当少的记录信息。
COPY(复制)实用工具集不复制由于块删除或者表清除所造成的空页。
当表达到一个特定的尺寸,它们的可管理性和性能都可以通过分区表空间获得改善。如果你想获得这方面的进展,在设计和创建时,以分区的形式定义表空间是一个明智的做法。分区表空间的一些潜在优势列举如下:
并行性:你可以利用三种类型的并行性,它们目前正应用于DB2 UDB。DB2 V3引入了查询并行性(多个I/O路径)。DB2 V4则实现了CP并行性(多CP之上的多任务)。DB2 UDB V5更是引入了系统查询并行机制(多个DB2数据共享群之上的多任务)。DB2的发展进化,显著提高了DB2应用程序处理分区表空间的并行处理能力。由于CPU时间的增加,这些查询所消耗的时间也显著的减少了。
在数据的一部分上工作:分区表空间允许DB2应用程序一次运行数据的一个分区,因而使其能够同时运行另外分区上的另外的工作或者应用程序。以同样的方式,你可以将块UPDATE(更新)、DELETE(删除)或INSERT(插入)操作分解为独立的工作。除增加了可用性之外,这一技术也为完成这类DB2工作减少消耗的时间提供了可能。
更快的访问被频繁访问的数据:如果分区索引能够将更多的频繁访问的行从剩余的表中分离出来,然后将那些数据置于一个它自己的,并且应用更高速DASD设备的分区之内。
一般而言,表越大,就越应该将其创建为一个分区的表。但是也有一些实际例子表明为小表创建分区表空间是有利的。当查找表用于连接其他大分区表空间时,通过将查找表分区,你能够使并行性在连接中最大化。
当你在连接谓词中利用分区方法时,需要考虑一个决定性的因素。被连接在分区方法上的表应该具有相同的分区数,并且应该设定为相同的值。
数据压缩
DB2提供了压缩表空间或分区内数据的功能。通过指定CREATE TABLESPACE(创建表空间)语句中的 COMPRESS YES(压缩许可)选项,之后在表空间上同时执行LOAD或REORG实用工具集,即可完成该功能。数据的压缩是通过用更短的串来替换频繁出现的字符串实现的。系统还创建了一个字典,包含了原始字节串和它们的替代串之间的映射信息。
一定数量的CPU资源被用于在执行数据存储对其进行压缩,之后,当外部存储设备读取时,数据又被解压缩。然而,数据压缩也能够提供性能方面的好处,因为更多的数据存储在更小的空间内(在DASD上和缓冲池中);同未经压缩的数据相比,这样可以产生更少的同时读取、更小的I/O等。
接下来是当试图决定是否压缩一个表空间或分区时,需要考虑的一些事情:
行的长度:行越长(尤其是在接近页的尺寸时),压缩的有效性就越低。DB2的行不能够跨页,当一页上有多于一行的情况时,你也许不能获得足够的压缩。
表的尺寸:对于较大的表,压缩具有较好的效果。对于很小的表,压缩字典的大小(8KB到64KB)可能会抵消压缩节省下的所有空间。
数据中的模式:对于一个特定的表空间或分区,数据中重复出现的模式的频率,决定了压缩的效果。含有大量重复字符串的数据能够获得显著的压缩效果。
压缩估计:DB2提供了一个单独的实用工具集,DSN1COMP,它可以用来测定数据压缩将有怎样的效果。想获得有关运行该使用工具的额外信息,请参考DB2实用工具集指南和参考手册。
处理成本:在压缩和解压缩DB2数据时,会消耗一些CPU资源。如果你用IBM的同步数据压缩硬件特征,所消耗的CPU资源将比利用DB2软件仿真程序低得多(当DB2启动时,这决定了硬件压缩特征是否可用)。
更好的字典:当用LOAD使用工具集来建立压缩字典时,DB2用户用最初载入的n行(n取决于你能够压缩的数据量)来决定字典的内容。REORG采用取样技术来建立字典。它不仅使用最初载入的n行,还在实用工具执行UNLOAD(未载入)阶段的剩余时间里继续对数据行采样。
通常情况下,我们推荐你在自己的特定环境下,压缩那些DB2表空间和分区,这将会使你的环境受益;因为在更小的空间内存储更多的数据的性能优势,几乎总是在价值上超过压缩和解压缩数据所消耗的CPU资源。
载入大表
在处理大批量数据时,将数据初始载入表中可能会对系统性能产生挑战。为了在载入过程中实现并行性,你可以手动创建多个LOAD作业,每个分区建一个;或者作为另一个选择,你可以在一个LOAD程序中载入多个分区。每个分区都延伸至I/O子系统,这种方式可以更容易地实现最理想的并行性。
为了使性能最优化,在LOAD语句中指定SORTKEYS参数也很重要。这个参数指示DB2将索引方法传递给内存中的分类程序,而不是将关键字写入或者再次读取DASD上的排序任务文件。SORTKEYS也能够实现载入和分类之间的交迭,因为分类是作为一个独立的任务运行的。
还有一些关于载入大表的额外的建议,如下:
一次LOAD一个表。
如果可能的话,为你预期的任务赋予较高的优先级,来获得最高的消耗时间。
在系统综合体上分配工作。
将二级索引分解为小段,以便获得并行性(见PIECESIZE内的讨论)。
在数据的初始载入过程中,指定LOG NO(用于防止记录日志,它耗费了相当多的资源),在成功载入数据之后运行一个图像复制。
自由空间考虑事项
分配自由空间的主要目的,是为了将数据行保存在相同的物理序列中作为群集索引,这样一来将减少需要重新组织数据的频率。此外,较好的行聚簇将导致更快的读取访问和更快的行插入。但是,自由空间的过度分配又将导致DASD空间的浪费、每一个I/O传输的数据较少、缓冲池的利用效率较低,以及需要扫描更多的页。
表空间和索引中的自由空间分配,由CREATE或ALTER TABLESPACE和CREATE或ALTER INDEX 语句中的PCTFREE和FREEPAGE选项决定。
PCTFREE在载入或者重新组织数据时,为DB2指示表空间或索引中有多大的百分比是闲置的。在插入新的行和索引条目时,DB2将利用那些自由空间。如果没有足够的自由空间在正确的页(即以正确的聚簇序列)上写入行或者索引条目,那么DB2必须将多出来的数据放在另外的页上作为代替。在越来越多的记录放置在物理序列之外的情况下,系统性能将会受到严重影响。
FREEPAGE在载入或者重新组织数据时,为DB2指示一个整页成为自由空间的次数。例如,如果你将FREEPAGE确定为5,在每填满5页的数据之后,DB2将分配一整页的自由空间。如果你的表中的行大于半页,FREEPAGE将是很有用的,因为在这样的情况下,你不能在这一页中插入第二行。
是否在你的表空间内定义自由空间,分配的数量又是多少,这些都主要取决于表空间中表的插入特性(删除活动性居于次要程度)。换句话说,向表中插入行有多大的频率,并且这些行插入的位置是在哪里?根据上述标准,四种主要的类别如下:
只读表:如果在表上不会有任何修正,定义时就可以不分配自由空间。同样,也就不需要运行REORG实用工具集。
随机插入:对于含有相当大数量已有行和相对较少插入行的动作的表,使用默认的PCTFREE(表为5,索引为10)是一个好的起始点。之后,用RUANSTATS来监视数据组织破坏的程度,并且结合你要求的运行REORG的频率,根据需要上调或下调PCTFREE。对于插入活动很频繁的表,你可能需要使用比默认值较高的PCTFREE的值。对于初始为空或只含有极少数行的表(例如,在一个新数据库部署的过程中),你也许需要确定一个非常高的PCTFREE值,并相当频繁地运行REORG,直到表中的行数比较多了。
在表的末端插入:如果表中行的长度不增加,那么就没有必要分配自由空间,因为它们可以加在表的末端。而且既然它们是以物理聚簇序列的形式写入的,REORG也不需要了。但是如果表含有可修改的VARCHAR类型的列,或是如果表是压缩过的,那么行的长度有可能增加,这将使得一行被挤到另外一页上去。通过在表空间上执行RUNSTATS然后核查DB2目录表SYSIBM.SYSTABLEPART的NEARINDREF和FARINDREF列,你就能够确定这些。如果你的表变乱了,那么为表空间设定一个PCTFREE值,并且用RUNSTATS继续监视放错位置的行的数目。根据你观察到的数据和趋势,相应地调整你的REORG的频率和PCTFREE值。通过设定REORG TABLESPACE中的INDREFLIMIT和REPORTONLY选项,你就能够在更新后的DB2表中监视紊乱的数量和速度。
插入一个热点:这是表具有很频繁的插入活动的情况,这种插入活动集中在一个位置(或多个位置),而不是正好处于表的末端。这可能是要应付的最困难的种类。试着增加PCTFREE的数值。如果插入保持在开头的段,行也不是很长,几行可以存储在同一页之内。FREEPAGE是在这种情形下另外的一个考虑。有必要严密监视表变乱有多么快,这样就可以在性能显著下降之前运行REORG。
索引设计考虑事项
索引是一个DB2对象(独立的VSAM数据集),它是从相应表中的一个或更多列中摘录出来的一系列有规则的条目。很多DB2专家主张为一个表空间建立恰当的索引,这也许是将访问DB2数据应用程序的性能最优化的惟一最有效的方法。几年前,在I/T中DASD的成本和空间是一个更重要的考虑因素。随着技术的发展,通过以特大硬盘为代价,加上更多索引(或增加现有索引的列)来减少I/O的折中方法,在这几年里越来越具吸引力。索引主要的性能优势表现在:
为表中被请求的数据行提供直接指针
消除了排序,如果结果集的请求顺序与索引相匹配的话
避免了必须读取数据行,如果被请求的列全部包含在索引条目中的话
分区索引
当在DB2 UDB V7中创建分区表空间时,DB2依照CREATE INDEX语句中的PART子句将分区中的数据进行划分。那个索引则成为所谓的分区索引,这种分区方法被称为受控索引分区。为了对索引进行分区,建议你选择不易改变的关键列。对这些列的更改可能使得一个行从某一分区移动到另外一个分区,从而导致性能下降。
受控表分区是DB2 V8的一个重要的特征。现在,当创建分区表时,分区界限的确定由CREATE TABLE语句代替了原来的CREATE INDEX。在受控索引分区中,分区表的、分区索引和聚簇的概念全都结合在一起。而对于受控表分区,这三个概念是独立的。这就增加了灵活性,允许你去考虑更有潜力的设计方法;并且也因此增加了改善DB2数据库及其应用程序性能的可能性。
构建索引的时机
CREATE INDEX(创建索引)
CREATE INDEX语句使用户具有了这样的能力:立即构建索引,或者将构建推迟到更加方便的时间。如果你立即构建索引,将会对表空间进行扫描,这会占用相当长的时间。通过设定DEFER,你可以推迟索引的构建。
无论什么时候,只要可能,在最初载入一个表之前创建表上的所有索引,因为LOAD实用工具集构建索引比CREATE INDEX过程更加有效。如果你需要在已存在(并且有很多数据)的表上创建一个索引,那么可以使用DEFER语句。稍后,你就可以用REBUILD INDEX实用工具集,它和LOAD实用工具集一样,是一种更加有效的填充索引的方法。
PIECESIZE(片段尺寸)
DB2 UDB V5引进了一个新特征,它给了你一定的灵活性,从而可以将非分区索引(NPI)分解为小段,并且控制组成索引空间的多个数据集的大小。分段的这种用法能够使一个NPI的索引页展开为多个数据集。
片段的尺寸由CREATE或ALTER INDEX语句中的关键字PIECESIZE确定。PIECESIZE的值必然是两个强制值中的一个,其变动范围为最小256KB到最大64GB。常规表空间的默认值为2GB,大的表空间默认值是4GB。如果你的NPI有可能显著增长,那么选择相对较大的表空间。同样,在确定首要和次要的空间分配数值(CREATE INDEX语句的PRIQTY和SECQTY选项)时,记住PIECESIZE的值。
利用这一选项,可以通过发挥并行性来改善NPI的扫描性能。另一个优势是可以减少读取或更新过程中的I/O冲突。通过设定较小的PIECESIZE值,你可以创建更多的片段,因而对片段的位置有更好的控制。将片段置于独立的I/O路径,可以减少了访问NPI所需的SQL操作的冲突。
理想的索引
通过检查一个应用程序中的SQL语句,你可以建立一个假想的完美的索引。
首先,索引所包括的所有列都是WHERE子句,这使得索引的审查可以用于将不合格的行拒于结果集之外。将这些列放在索引的开始。当在SQL语句上执行EXPLAIN时,这会使得MATCHCOLS的价值最大化。
其次,确保索引以适当的顺序含有这些列(依照ORDER BY子句),从而可以避免进行排序。这可以在执行EXPLAIN时,通过检查PLAN_TABLE的所有不同的SORT*列来验证。
最后,如果可能的话,将所有的列包含在索引的SELECT中,这样就不需要访问表中的行了。索引条目可以提供所有的请求数据。这将在EXPLAIN中以INDEXONLY = Y的方式表现出来。
在很多情况下,实现如此理想的索引的代价太大了,或者说是不切合实际的,甚至是不可能实现的,因为所涉及的列的数量太大了。组成一个索引的列的数目在体系结构方面有限制,并且对于一个索引条目的总长也有限制(尽管这些限制实际上允许相当大的索引条目尺寸和灵活性)。此外,这也是出于索引维护成本的考虑。建立理想的索引可使查询性能获得极大提高,但是对于SQL写入DB2数据库(INSERT、UPDATE或DELETE)就有消极的影响。因此,你应该经常选择实现只包含WHERE和ORDER BY语句中涉及的列的索引。
并行处理的考虑事项
几年来,通过实现了并行处理的各种方法,DB2在数据访问方面的性能获得了改进。为了改进数据密集型只读查询的性能,DB2 V3引进了查询I/O并行机制。在这种类型的并行性中, DB2充分利用了可用的I/O带宽,并使分区表空间中成为可能。利用这种方法,DB2使得一个查询中的多个并发I/O请求可同时进行,并在多个数据分区中执行了并行的I/O处理。这代表性地使得I/O绑定查询所耗费时间的显著降低,同时出现了CPU时间的较小增长。
DB2 V4引入了另外的并行性技术,称为查询CP并行性。该方法将并行处理扩展至处理密集型的查询。用该方法,单个查询可使DB2生成数个任务,并行执行数据访问。对于这种类型的并行性,分区表空间显示出最佳的性能提升。
DB2 UDB V5通过引进综合系统查询并行性,更进一步地扩展了并行处理。当查询CP并行性在DB2子系统中为某个查询使用了多个任务时,该方法使得DB2数据共享群中的所有成员能够处理一个单一的查询。主要为只读形式的I/O密集型和处理密集型查询可以从这种类型的并行性中获益。
并行访问的授权
在DB2环境下使系统获得并行性能力有一定的难度。首先,在DB2子系统级别,并行访问由安装面板DSNTIP4控制。DSNTIP4上的MAX DEGREE 选项决定并行性的最大程度(并行任务的最大数目)。默认值为0,意味着对于DB2可调用的并行性程度没有上限。我建议你估计虚拟存储容量,以及你的z/OS环境限制,还应根据需要调整该参数,因此DB2将不会创建超过你的虚拟存储容量可以应对的并行任务。
通过BIND PLAN和BIND PACKAGE命令的DEGREE选项,你能够控制DB2是否使用并行处理。设定DEGREE(1)阻止并行处理,而DEGREE(ANY)允许并行处理。为了获得进一步的灵活性,动态SQL允许在一个计划或包内更改该选项,通过SET CURRENT DEGREE语句即可实现,SET CURRENT DEGREE语句用于控制某个寄存器中的数值。
当一个计划或包与DEGREE(ANY)绑定,或者CURRENT DEGREE寄存器设定为ANY时,DB2优化器考虑并行性是否是可能的,从而获得最有效的最终计划。如果并行性是不可能的,那么将会选择下一个允许并行性的最有效的最终计划。
限制分区扫描
限制分区扫描是允许DB2在分区表空间中限制数据扫描的一种方法。根据SQL谓词的值,DB2能够决定最低和最高的分区,这可能包含了被SQL语句所请求的表的行,之后便将数据扫描限制在分区的范围内。为了使用该技术,SQL必须提供一个在分区索引的第一个关键列上的谓词。
并行性建议
为了使并行处理的性能最优化,需要考虑以下事项:
尽可能均匀地对表空间进行分区,因为并行性程度会受到数据不均匀的影响。DB2通常在最大物理分区的基础上将表空间划分为逻辑片段。
为DB2的应用程序处理分配尽可能多的中央处理器(CP),以及尽可能多的I/O设备和通道。
对于I/O密集型查询,确保分区的数量与可以访问表空间的I/O通道数量相同。
对于处理密集型查询,确保分区的数量与用于跨共享数据群处理查询的CP数量相同。
将表空间和索引的分区放在单独的DASD卷上,并且(如果可能的话)独立控制这些单元以便使I/O冲突最小化。
在规则的基础上执行RUNSTATS实用工具集,以便获得分区级别的统计表。
监视虚拟缓冲池的阈值和使用情况,确信你提供了足够的缓冲池空间来使调用的并行性程度最大化。
缓冲池的考虑事项
缓冲池的重要性
大多数专家认为在DB2环境下,数据库缓冲池是影响性能的最关键的因素。很多DB2的体系结构和设计是基于尽可能多的或实际上避免物理I/O这一概念。
DB2缓冲池由临近存储器的插槽组成。从DASD读入之后,数据和索引页进入这些插槽并且呆在其中,直到DB2缓冲管理器决定这些插槽需要被其他数据占用。被应用程序请求的数据通常存储在存储器内,而不是在外部的DASD,这种情形越经常出现,整体的性能就越好。本质上,数据是被重新利用了,从而使得应用程序需要的I/O数量最小化。
释放缓冲池插槽的决定基于最近最少使用(LRU)法则。DB2维护着两个LRU列表,一个是关于随机访问页的,另一个是关于顺序访问页的。这便阻止了完全占用缓冲池的大表扫描,以及对随机操作的负面影响。通过各种阈值的使用,DB2为你提供了改进缓冲池性能的额外灵活性。关于这些阈值的进一步详细讨论见DB2 SQL参考手册的2.7.4部分。
缓冲池的合适大小
缓冲池尺寸的指定取决于可用的存储量(包括中央部分和扩展部分)。我建议你分析一下缓冲池分配,并且增加它的尺寸直到再也没有由于增加的分配而产生的额外吞吐量,或是MVS分页速率到达不可接受的程度。这将通过逐渐增加的VPSIZE来实现,只要DASD I/Os的数目保持减少,在分页的成本超过减少I/O的收益之前,VPSIZE将持续增加。
在早期,GETPAGES的数量可能是DB2工作量的最好衡量标准。缓冲池的用途是为了使I/O最小化(异步读取通常意味着一次做一个,这是基于性能立场上的一般要求。另一方面,同步读取通常意味着从DASD的随机I/O,因为所请求的页在缓冲池内找不到)。统计报告显示le 每一个缓冲池中的GETPAGES和同步读取的数量。一个被普遍接受的ROT说,如果同步读取的GETPAGES比率小于10:1,那么你应该考虑配置更大缓冲池了。
多缓冲池配置
如果你的操作环境允许为DB2缓存配置容量相当大的存储器,那么多缓冲池配置可以最大限度地为特定的应用程序或数据库提供改善的性能。然而,请注意由于采用多个缓冲池,监视它们的工作效率变得更加重要。
普遍来讲,对配置多缓冲池有如下建议:
将表空间和它们相联系的索引分离到不同的池,以便使索引I/O最小化。
将具有不同数据访问模式的数据分别置于不同的缓冲池中。典型地,批处理和查询应用程序含有大量的连续处理,而OLTP的数据访问在本质上往往比较随机。这就提供了一种方法,来开发不同的阈值以在一个缓冲池适应各种特定类型的数据访问。
为了隔离应用程序,提供一个单独的缓冲池。这就提供了一种方法,来严密监视一个存在运行问题的应用程序,或是测试新的应用程序。
如果分类性能在你的环境下很重要,那么就为共作文件创建一个独立的缓冲池。
对于相对比较小但是更新很快的表,足够大的独立缓冲池可以同时消除读取和书写I/Os。
为只读表(小的、参考表)设立单独的缓冲池也可以提高性能。
总结
经过深思熟虑的数据库设计可以提供重大的性能优势,但是它必须在应用程序的开发过程中尽早开始。上述很多原则,在DB2的早期就已经被明智的开发人员所利用,并且至今仍保持着它们的正确性。然而清楚DB2功能上的进步,以及影响你当前和以后应用程序的其他领域内的硬件和软件技术的变化,同样也是至关紧要的。当数据库性能成为发展过程的一个重要焦点时,你的数据库设计,将使你更有可能为你的DB2应用程序提供最优化的性能。
本文章转自IBM DeveloperWorks