DB2数据更新问题

开发工具:PB
数据库:DB2
需要更新客户的零件价格信息和其他的相关信息,每次更新数据会有2800000条左右,目前的程序需要执行11个小时才可以完全结束。
实现方法是用DATASTORE来Update的,客户仍然感觉很慢,请教各位大神,有什么其他的好一点的办法可以进一步的提高效率吗?

按照你的说法,是先从一个表(假定表名为A)里读取1000行数据,然后到正式表(假定表名为B)里分别判断每条记录,如果没有这条记录就INSERT到正式表,如果正式表有这条记录就UPDATE正式表的数据,然后再处理下一个1000行。我这个理解正确吗?

如果是这样的话,从A表取数据的WHERE条件中的谓词应该建成一个复合索引,并且排序字段建成一个单独的索引(rownumber() over(order by 排序字段 asc ) as rowid),这样能很大程度上加快读的速度,这个语句频繁执行,是优化的关键点。
接下来判断每条记录在B表是否存在,这个WHERE条件中的谓词也应该建成一个复合索引,因为这个语句会频繁执行,也是优化的关键点。
然后是判断,不知道你用的是什么语言来实现,这个地方已经跟数据库没有关系了,无法优化。

接下来是插入,如果能批量操作,就考虑批量,比如JDBC的接口中addBatch()等方法,同时给B表添加append on特性,可以很大程度的加快插入速度,是优化的关键点。使用append 特性以后,请注意定期reorg table,alter table TAB_NAME append on。
接下来是更新,同样是做成批量操作,这个UPDATE的WHERE条件中的谓词也建成一个复合索引,这个语句频繁执行,也是优化的关键点。

然后数据库层面:
日志缓冲池(LOGBUFSZ)调整成8192个页面,可以减少日志I/O,这个也是优化的关键点;
活动日志、归档日志所在的磁盘与数据所在的磁盘要分开,因为I/O是数据库最耗时的操作,瓶颈一般都处在这个地方,这个也是优化的关键点;
数据和索引及大字段分开存放在不同的表空间,数据和索引不要用文件缓存,大字段启用文件缓存;
索引使用的缓冲池最好保证索引完全能够容纳进去,这样能很大的加快查询速度,这也是优化的关键点;
日志文件大小最好定义为100MB,主日志大小定义为10,辅助日志大小定义为20,即LOGFILSIZ=25600,LOGPRIMARY=10,LOGSECOND=20,这样可以减少日志频繁归档和保证一个事务可以进行更多的DML操作;
每次操作不要只对1000行记录进行操作就提交,因为频繁提交很耗时,建议调整为每次2W条,上面所说的日志配置应该足够确保不会出现日志空间满的问题。

我在银行的批处理操作中做过12个参数表的这种临时表、正式表、查询、判断、INSERT、UPDATE的操作,总数据量有14W条记录,操作时间都是在10分钟以内结束,而且是一台服务器上三个环境都有这样的作业在同时执行(即访问临时表和正式表中不同的记录)。
按照这个估算,你的280W条记录,应该可以在200分钟内结束。

我程序中用到的是JAVA、MYBATIS、SPRING的手动事务。
附:我拥有DB2 V9的所有认证,希望我的回答对你有所帮助。
温馨提示:答案为网友推荐,仅供参考
第1个回答  2014-01-22
update本身是比较慢的,你可以将更新的条件增加索引,必要的时候增加组合索引.
其实最好是整型的数字字段,比如主键作为条件,能很大的提高速度.
另外,你可看表的数据量,如果更新的数据是全部,或者是绝大部分,建议你把不更新的导出,然后分别插入不更新的,和已经修改过的价格.追问

恩,有一张的表的数据比较多,考虑过你说的,现在正在和客户沟通,因为他们有可能会取那张表的历史数据。可以将更新的东西写到存储过程吗,那样会不会快一点。

追答

存储过程也是追条执行的,性能上没啥差别的.
如果历史数据是增量,且访问不频繁,建议单独存放一张表;
而经常访问的实时(每次更新的)数据,也单独放一张表;
这样做可能会增加一个界面,或者说走个分支接口,但是对客户体验上来说性能还是有很大提高的.
另外,可以考虑分区(比如按照时间,这种分区方式较为常用),这个你可以研究下.

追问

按照现在程序里面的逻辑,历史数据的确是增量,理论上来说,客户是不会取很早之前的数据的,之前我们也考虑过分两张表存放,但是现在客户也没有具体回复,所以我们也没法决定对那部分历史数据的处理方案。
现在我正在对每部分的时间做测试,看那部分花的时间最长,到时候在做优化吧。

追答

客户没回复,你也只能在现有的基础上优化了,加油~

第2个回答  2014-01-23
批量的去更新,每次批量设置一定数量,如1000条或10000条commit一次。追问

现在就是这么处理的,但是每一条都需要去表里校验有没有这个数据,有就UPDATE,没有就INSERT。也是挺耗费时间的。