DML 性能问题
DML(Data Manipulation Language) 包括了查询,增加,删除和更新纪录等操作。
首先看一下查询的性能问题,在查询一张表或多张表的联合查询时有时反应时间会比较长,这使得用户难以忍受。针对这种问题,可以通过下述方法来分析:
在查询的连接或条件子句中的相关字段是否加了索引。 ( 关于 SQL 的优化可以参见 SQL 优化相关文章,本文不再赘述 ) 。
察看缓冲池的大小,缓冲池太小会造成很多数据不能读到缓冲池而直接从硬盘上读取,造成很大的瓶颈。另一方面关于缓冲池预取的设置,一般能将预取大小 (PREFETCHSIZE) 设定为区段大小与容器个数的积,这样可以最大利用到预取的并行性。
在查询中涉及到 order by 字句时,如果排序的字段没有设置索引那么排序将会用到内存中的排序堆 (sortheap) 。如果排序堆过小会造成排序溢出到硬盘上 (Overflowed) 造成性能衰退。
同时还要考虑到 RUNSTATS/REORG 因素。 RUNSTATS 命令可以更新表中的统计信息。当表中的数据经过频繁的增删改后其相应的统计信息会发生变化,而优化器选择执行计划的时候是根据这种统计信息来计算的,所以 运行 RUNSTATS 此时显得尤为重要。 REORG 可以整理数据存储的物理结构,也能减少数据扫描的时间,提高查询的性能。
从存储方面应当注意的是选取裸设备的 DMS 要比 SMS 性能要好,因为它少了一层文件系统的缓冲而直接访问缓冲池。
学会使用 optimize for n rows 子句,它可以提高前面 n 条记录的显示速度。这样可以使用户能够先快速查看这 n 条记录,然后再看其他纪录。减少了用户的等待时间。
物化查询表 (MQT) 也是提高查询性能的一种手段,它可以将经常用到的查询结果集存储到一张中间表中,在查询时减少了数据检索的时间。
在架构上采用 MPP 或 SMP 也是提高查询或写操作性能的手段。
针对复杂查询时可以将数据库配置参数 DFT_QUERYOPT( 缺省查询优化类 ) 的值设得高一些(7 或 9),针对简单查询可以将它设得低一些 (3 或 5),因为设置越高优化器所作的分析就越深入,耗费在生成计划上的时间就越多。
针对 C/S 结构的查询可以将查询语句写在服务器端生成存储过程来减少数据的网络传输以及客户端的压力。而经过编译的存储过程执行得更加高效。
还要考虑到隔离级别与锁的因素,隔离级别越高越能保证数据的完整性,但同时会减弱并发性。这一点需要权衡需求而定。
网络因素也不可忽视,将数据库服务器参数 RQRIOBLK 设为 65534 可以相应地提高网络吞吐量。(缺省值 32767)
最后需要考虑的是数据库的结构,在某些情况下,在某些表中增加一些冗余字段虽然牺牲了一些空间和维护成本,但是在查询时可以减少很多连接操作,这样可以大大提高查询性能。就是用空间换取时间。
接下来看一下增删改的性能优化方法:
首先是索引因素,在做增删改时数据库会对表中的索引做相应的修改。这会消耗一定的资源,所以在保证数据完整性的前提下可以先将索引删除,待到增删改结束后再重建这些索引。这也会节省一些时间。将索引和数据放在不同的硬盘上也可以增加写操作的并行性。
其次要考虑日志因素,在数据写操作的同时,数据库系统也在维护着事务日志,所以应尽量减少日志维护 的代价。将 auto commit 设为 false,可以减少提交的次数(同时也减少了写日志的次数)。增大 LOGBUFSZ,LOGFILSZ 可以减少刷新日志的次数以及日志文件切换的次数。或者将表的属性改为” ACTIVATE NOT LOGGED INITIALLY ” , 这样可以屏蔽表的日志操作,以提高写操作的性能,但是失去事务日志的表的数据很难修复,这一点需要权衡。
将日志和数据分别放在不同的硬盘上也可以增加写操作的并行性。
在插入记录时采用 APPEND MODE 可以消除 DB2 寻找表中间的空余空间的时间而直接插到表尾,从而提高插入的性能。
关于并行性的因素,采用 MPP 模式可以使用并行处理的方式增加写操作的性能。将容器分散在不同的硬盘上也可以增加写操作的性能。
还要考虑到约束和触发器的影响,在写操作时应当尽量避免表中有约束和触发器。在保证数据完整性的前提下可在频繁大批量写操作时先将约束或触发器去除,完毕后重建。
和查询一样,写操作同样要考虑到隔离级别和锁的因素(参见查询优化部分)。
在 insert 语句中包括多行可以减少客户机 - 服务器通信次数,提高插入性能。如:insert into table1 values (1, ’ a ’ ),(2, ’ b ’ ),(3, ’ c ’ ) 。
还有一个需要考虑的因素是 DB2 V95 在 UNIX 上的采用线程模型,在操作系统中的开销变小,使得写操作性能要比之前的 DB2 的版本要好。
本文出自seven的测试人生公众号最新内容请见作者的GitHub页:http://qaseven.github.io/