DB2 性能优化是一件较为复杂的综合性的工作 , 需要对问题的根源作全方位的探索和思考。同时也需要较深厚的数据库管理经验与优化知识。这对于初学者来说可能有些勉为其难。但是在很多情况下,随着 DB2 数据库中的数据量的不断增长或者用户数的激增,数据库系统的性能会显著下降,而此时快速定位性能上的瓶颈则至关重要。下面简要地介绍一下 DB2 的调优的一些因素和工具,以及一些原理,使初学者对性能优化能够有一个大致的了解。
DB2 的性能优化可以从三个方面分析:内存,CPU 和 I/O 。
在内存方面,主要是考虑缓冲池 (BUFFERPOOL) 的使用。缓冲池是一片用来缓冲从磁盘上读取的数据和索引的内存区域,这些数据和索引信息在缓冲池中进行运算后最终还要写回磁盘。缓冲池的页面大小有四种 (4K,8K,16K,32K),分别对应四种不同页面大小的表空间。缓冲池的大小决定了能够从磁盘上缓冲数据的容量大小。当然缓冲池也不是越大越好,缓 冲池过大可能会导致连接数据库的时间过长,因为在连接数据库时要为数据库的缓冲池分配内存空间。可以通过计算缓冲池的命中率来评估缓冲池的使用效率:缓冲 池命中率 =(1-(( 数据物理读 + 索引物理读 )/( 数据逻辑读 + 索引逻辑读 ))) *100%,缓冲池命中率越大说明缓冲池的使用效率高。缓冲池命中率太小说明缓冲池太小应当调大。其中的数据物理读,索引物理读以及数据逻辑读和索引逻辑 读都可以从缓冲池的快照中获取。
在内存方面要考虑的另外几个重要因素是排序堆 (SORTHEAP),锁列表 (LOCKLIST), 日志缓冲区 (LOGBUFSZ) 。排序堆在查询结果带有排序选项而没有相关索引对应时将会被使用,排序堆太小会产生排序溢出 (Overflowed), 那些在排序堆中装不下的排序数据将会溢出到一个临时表中,这会使性能下降。与 SORTHEAP 参数相关的是 SHEAPTHRES_SHR 和 SHEAPTHRES,SHEAPTHRES_SHR 限制了一个数据库中共享排序的最大内存,SHEAPTHRES 限制了私有排序的最大内存。 LOCKLIST 指的是一个数据库中用来存放锁的内存空间,当这个参数设得过小会导致在锁用光这部分资源后导致锁升级(即多个行锁转化为一个表锁来释放出更多的资源)。这 会导致系统的并行性下降,很多应用连接出现挂起,使得系统的性能衰退。所以尽可能调大 LOCKLIST 参数,这里需要指出 LOCKLIST 指的并不是锁的个数,而是以数据库页为单位的一片内存区域(在 32 位系统中每个锁需要 96 个字节,锁上加锁的话每个锁则需 48 个字节。在 64 位系统中每个锁需要 128 个字节,锁上加锁的话每个锁则需 64 个字节)。与 LOCKLIST 参数对应的是 MAXLOCKS 参数,MAXLOCKS 定义的是一个百分数,它指定了一个应用程序所能占用的最大的锁空间占 LOCKLIST 的比例。日志缓冲区 (LOGBUFSZ) 指的是日志在写到磁盘以前用于缓冲的一片内存空间,这样可以减少写日志带来的过多的 I/O 。
从版本 9 以后 DB2 推出了一个新特性自调节内存管理器 (STMM: Self Tuning Memory Manager), 这个特性使得很多内存参数如前面所述的 SORTHEAP,LOCKLIST,LOGBUFSZ 等进行自动调节,当数据库参数 SELF_TUNING_MEM 设为 ON, 这些参数设为 AUTOMATIC 即可以进行自动调整。这样可以节省很多人工调整的时间。
关于 CPU 因素首先是考虑 DB2 优化器 (OPTIMIZER) 对访问计划 (ACCESS PLAN) 的分析与优化。一般来说,一条 SQL 在执行时首先会被解析,然后进行语义分析,进而重写 SQL, 优化器会对重写过的 SQL 进行基于成本的分析最终选择最有效的访问计划。最终生成可执行代码(执行计划)来执行这条语句。查询访问计划的工具有很多,既有图形化工具 Visual Explain,也有命令 db2exfmt 来格式化解释表 (Explain tables) 中的数据生成 ACCESS PLAN 。还有命令 db2expln 查询 ACCESS PLAN 。
在 DB2 里的优化级别分为九级,缺省是第五级,级别越高优化器分析得程度越深。这个级别有数据库配置参数 DFT_QUERYOPT 决定。并不是级别设得越高性能越好,因为对于一些较为简单的 SQL 语句,如果优化级别过高那么花在优化 SQL 上的时间就会过长,而执行时间相对来说很短,有些得不偿失。在选择访问计划时,索引扫描的效率往往会比表扫描要高,所以索引的优化也是值得注意的。正确的 建立索引会使查询性能大幅度的提高。
在 DB2 中连接 (JOIN) 分为三种:嵌套循环连接 (nest-loop join), 合并连接 (merge-join), 散列表连接 (hash-join) 。一般来说效率最低的是嵌套循环连接,这种连接采用的是笛卡儿集,进行多次循环遍历得到结果。而合并连接和散列表连接只进行一次循环遍历,相对来说效率较 高。其中散列表连接可以采用多个等式做为条件而合并连接只能采用单个等式作为条件。但是在有索引扫描的情况下嵌套循环连接效率则更高。当优化级别等于零 时,连接只能采用嵌套循环连接, 当优化级别大于等于 1 时,连接可以采用合并连接。当优化级别大于 5 时连接可以采用散列表连接。散列表连接要求 SORTHEAP 比较大,因为要为生成散列表准备空间。
在考虑 CPU 因素时还要考虑 CPUSPEED 这个参数,这个参数标明了 CPU 的运行速度,它会帮助优化器评估最好的访问计划。一般来说这个参数设为 -1,优化器将自动计算 CPU 的速度。另外运用多分区的特性可以把一个数据库分布到多台机器上,这样可以充分利用多台机器的 CPU 的资源对应用程序的事务进行并行处理,从而提高数据库的性能。
关于 I/O 因素要考虑以下几个方面:首先是磁盘的 I/O, 为了能够最大化磁盘的 I/O 可以把数据,索引以及日志分别放在不同的硬盘上。因为在一个事务中数据和索引可能需要同时访问,而在事务提交时,数据和日志要同时写入磁盘,而且有可能索 引也要同步维护,所以将它们放在不同的硬盘上可以使它们的读写并行运行,从而不致使磁盘成为瓶颈。同时选择数据库管理表空间 (DMS) 要比系统管理表空间 (SMS) 性能要好,因为读写 SMS 需要经过操作系统的 cache 再到缓冲池,而可以采用裸设备的 DMS 则不需要。但是 DMS 相对 SMS 来说维护起来较麻烦。
其次要考虑的是日志文件的大小,当数据库在写事务日志时当一个日志文件写满后会转向另外一个日志文件,这种日志文件的切换会造成操作系统上的开销。所以应 当尽量将日志文件大小(LOGFILSIZ)设得大一些,这样可以减少日志文件切换的次数。但是日志文件过大难免会造成一些空间的浪费。
同时也要考虑到隔离级别的因素,在 DB2 中隔离级别分成 4 级:可重复的读,读稳定性,游标稳定性和未提交的读。这四种级别逐个降低。越高的隔离级别越能保证数据完整性,但却会降低并发性,所以应当综合权衡后做出决定。隔离级别可以通过如下命令来改变:
CHANGE ISOLATION TO=CS|RR|RS|UR
在连接方面还要考虑到代理和连接的关系,这也会影响到数据库的并发性,具体信息可以参考资源部分。
最后要考虑的还是关于多分区的特性。在多分区数据库中,一个请求首先传到协调分区,然后由协调分区将请求细分成多个部分发送到其他分区,这样数据可以在各个分区进行并行读写,实现 I/O 最大化。
在 DB2 中有很多和性能优化相关的工具和命令,下面简单地介绍几种:
还有一些 DB2 中其他的文件可以用来分析性能问题,比如说诊断日志,追踪文件等。一些第三方的工具也可供参考,如“ tivoli monitor for db2 ”, QUEST 等等。
DML(Data Manipulation Language) 包括了查询,增加,删除和更新纪录等操作。首先看一下查询的性能问题,在查询一张表或多张表的联合查询时有时反应时间会比较长,这使得用户难以忍受。针对这种问题,可以通过下述方法来分析:
接下来看一下增删改的性能优化方法:
先来看一下如何提高备份操作的性能:
再来看一下如何提高恢复操作的性能:
提高导入操作(import)的性能 :
提高导出操作 (export) 的性能:
提高载入操作 (load) 的性能:load 操作中日志的写操作比 import 要少,所以 load 的性能比 import 要好很多,下面还是看看如何更好地提高 load 的性能。
一般来说在连接数较少情况下,db2 的性能会比较稳定。因为这时连接的应用所产生的请求比 db2 代理池中所能产生的协调代理少,这时基本上能够满足每一个请求都能够被及时的协调代理所响应处理。 在连接集中器激活(MAX_CONNECTIONS > MAX_COORDAGENTS)的情况下,如果连接数超过了协调代理,这时连接所过来的请求就会进入队列等候协调代理服务,并发的连接数提高了,但是某 些连接的性能就会显著下降。此时应当考虑激活分区间并行 (SMP) 或多分区(MPP)特性来增加 I/O 的并行性以及多个 CPU 的并行运算。
接下来这里从一个试验来看一下 DML 操作过程中优化的详细步骤和具体数据。首先看一个查询优化的例子,下面是试验中的建表语句:
CREATE TABLE MCLAIM.T1_DMS ( C11 VARCHAR (10) NOT NULL , C12 VARCHAR (15) NOT NULL , C13 VARCHAR (20) NOT NULL , CONSTRAINT C11_PK PRIMARY KEY ( C11) ) IN DMS_Space; CREATE TABLE MCLAIM.T2_DMS ( C21 VARCHAR (15) NOT NULL , C22 VARCHAR (25) NOT NULL , C23 VARCHAR (30) NOT NULL , CONSTRAINT C21_PK PRIMARY KEY ( C21) ) IN DMS_Space; CREATE TABLE MCLAIM.T3_DMS ( C31 VARCHAR (10) NOT NULL , C32 VARCHAR (25) NOT NULL , C33 VARCHAR (35) NOT NULL , CONSTRAINT C31_PK PRIMARY KEY ( C31) ) IN DMS_Space; |
最初的环境没有优化,表空间类型 SMS 表空间,查询的表中没有索引,sortheap 过小等等。在这种情况下执行下列查询语句:
select C12 from TESTOPT.T1_SMS,%SCHEMA%.T2_SMS,%SCHEMA%.T3_SMS where substr(C12,1,10)=substr(C21,1,10) and C22=C32 order by C12 asc |
在没有优化的情况下得到的总的执行时间是 653 秒,而经过优化后得到总的执行时间是大概是 15 秒左右。在优化中采用了如下优化步骤:
CREATE UNIQUE INDEX INDEX_C12 on T1_DMS (C12 ASC); CREATE UNIQUE INDEX INDEX_C22 on T2_DMS (C22 ASC); CREATE UNIQUE INDEX INDEX_C32 on T2 _DMS (C32 ASC); |
ALTER TABLE T1 ADD C12_Red VARCHAR(10); ALTER TABLE T2 ADD C21_Red VARCHAR(10); UPDATE T1 SET C12_Red=SUBSTR(C12,1,10); UPDATE T2 SET C21_Red=SUBSTR(C21,1,10); |
select C12 from TESTOPT.T1_DMS, TESTOPT.T2_DMS, TESTOPT.T3_DMS where C12_Red=C21_Red and C22=C32 order by C12 asc |
从图中可以看出选择好的表空间类型 ( 数据库管理表空间 ) 和添加索引会对性能有很大的改善作用。而添加冗余字段对性能的改进作用最大。当然这会涉及表结构的变化,是需要在数据库设计阶段考虑的因素。同时代价是增加磁盘的占用空间。
接下来是一个写操作的例子(插入)。下面是试验的脚本:
CONNECT TO FFTEST; CREATE SCHEMA TESTOPT; DROP TABLE TESTOPT.T3; CREATE TABLE TESTOPT.T3 ( C31 VARCHAR (10) NOT NULL , C32 VARCHAR (15) NOT NULL , CONSTRAINT C31_A CHECK ( C31 LIKE 'A%' or C31 LIKE 'a%')); CREATE INDEX TESTOPT.INDEX_C31 on TESTOPT.T3 (C31 ASC); ALTER TABLE TESTOPT.T3 ADD CONSTRAINT C31_A CHECK (substr(C31,1,1)= ’ a ’ or substr(C31,1,1)= ’ A ’ ) ALTER TABLE TESTOPT.T3 APPEND OFF; CONNECT RESET; |
最初的表没有优化,含有索引,约束等因素,插入 4 万条记录大约花了 68 秒钟,而最终优化后插入 4 万条记录只需 6 秒钟。如下是优化步骤:
从图中可以看出减少索引和约束可以大幅度提高插入性能,而将多条插入语句合并成一行产生的效果更加明显。
复杂的应用环境中的性能优化 (DB2 Performance Expert)
现在的生产环境都是非常复杂的,性能问题涉及到了应用程序,应用服务器,数据库,网络等各种因素。要从复杂的环境中迅速定位性能的瓶颈非常困难。下面介绍 一个非常有用的工具可以帮助用户解决这个难题。这个工具就是 IBM 的 DB2 Performance Expert 。运用 DB2 Performance Expert V3.2 可以很快的找到系统的性能瓶颈。如下图所示:
从这个截图可以看出目前应用程序(灰色部分)和数据库(黑色部分)占用了很大的比例,是系统瓶颈所在。而下图则详细描述了数据库的一些状态信息。
从上图可以看出,排序溢出很大 ( 到了 100%),说明 sortheap 需要调整,缓冲池 IBMDEFAULTBP 的命中率很低(只有 69.5%),说明缓冲池太小,需要调大。所以在分析系统性能问题是使用 DB2 Performance Expert 是一个不错的选择。
通过本文对 DB2 的各项性能要素的分析以及性能工具的介绍,希望能使读者在分析性能问题时有一个清晰的脉络,从而由潜入深地去解决相关的性能问题。也希望初学者能够以此作为入门的台阶,开始深入系统地学习 DB2 相关的领域。
原帖:http://www.ibm.com/developerworks/cn/data/library/techarticles/dm-0906liyue/