经典资料,WORD文档,可编辑修改,欢迎下载交流。 致我不得不用cursor,速度慢。 如果显示调用存储过程时传 null值要注意 注意将null用大写表示,NULL 否则db2不认为是空。 5 DB2编程性能注意 5.1 大数据的导表的使用(export,load,import)(小心) 5.1.1 import的用法 db2 import from gh1.out of DEL messages err.txt insert into db2inst1.tb_dbf_match_ha db2 import from gh1.out of del modified by chardel; messages err.txt insert into db2inst1.tb_dbf_match_ha (column的分割符号改为;) 注意要加schma Import使用要特别注意: Import缺省使用RR隔离级别,且对表加锁,而且是加X锁。使用import一定要想清楚。 如果import时使用了replace选项,连select * from tbtmp with ur都不可以选记录,也会报错为timeout。不知道是怎么回事。好象这张表被加了Z超级排它锁一样。 另外,import时对syscolumns加了一些行锁,对systables加了表锁IS锁,而IS和X是不相容的。因此,这时候就不能创建和drop表了。 个人认为:如果要并发,还是使用insert比较好,虽然insert比较慢,但不会锁表,可以多个进程并发执行。 5.1.2 性能比较 应该是export后再load性能更好,因为load不写日志。比select into 要好。 5.1.3 export用法 db2 \to tb_head_pending_buyback.del of del select * from tb_head_pending_buyback\5.2 SQL语句尽量写复杂SQL 尽量使用大的复杂的SQL语句,将多而简单的语句组合成大的SQL语句对性能会有所改善。DB2的SQL Engieer对复杂语句的优化能力比较强,基本上不用当心语句的性能问题。 Oracle 则相反,推荐将复杂的语句简单化,SQL Engieer的优化能力经典资料,WORD文档,可编辑修改,欢迎下载交流。 21 经典资料,WORD文档,可编辑修改,欢迎下载交流。 不是特别好。 这是因为每一个SQL语句都会有reset SQLCODE和SQLSTATE等各种操作,会对数据库性能有所消耗。 一个总的思想就是尽量减少SQL语句的个数。 5.3 SQL SP及C SP的选择 首先,C的sp的性能比sql 的sp 的要高。 一般而言,SQL语句比较复杂,而逻辑比较简单,sql sp 与 c sp 的性能差异会比较小,这样从工作量考虑,用SQL写比较好。 而如果逻辑比较复杂,SQL比较简单,用c写比较好。 5.4 查询的优化(HASH及RR_TO_RS) db2set DB2_HASH_JOIN=Y (HASH排序优化) 指定排序时使用HASH排序,这样db2在表join时,先对各表做hash排序,再join,这样可以大大提高性能。据沈刚说做实验,7个一千万条记录表的做join取10000条记录,再没有索引的情况下要72秒。 db2set DB2_RR_TO_RS=Y 该设置后,不能定义RR隔离级别,如果定义RR,db2也会自动降为RS。这样,db2不用管理Next key,可以少管理一些东西,这样可以提高性能。 5.5 避免使用count(*) 及exists的方法 1、首先要避免使用count(*)操作,因为count(*)基本上要对表做全部扫描一遍,如果使用很多会导致很慢。 2、exists比count(*)要快,但总的来说也会对表做扫描,它只是碰到第一条符合的记录就停下来。 如果做这两种操作的目的是为select into 服务的话,就可以省略掉这两步,直接使用select into 选择记录中的字段。 如果是没有记录选择到的话,db2 会返回:sqlcode=100 和 sqlstate=?20000? 如果是有多条记录的话,db2会产生一个错误。 程序可以创建 continue handler for exception continue handler for not found 来检测。这是最快速的方法。 3、如果是判断是不是一条,可以使用游标来计算,用一个计数器,累加,达到预定值后就离开。这个速度也比count(*) 要快,因为它只要扫描到预定值就不再扫描了,不用做全表的scan,不过它写起来比较麻烦。 5.6 Commit的次数要适当 据马宏伟的测试, 一个50万条记录的表,有索引,update 或insert 一条记录是6毫秒。 经典资料,WORD文档,可编辑修改,欢迎下载交流。 22 经典资料,WORD文档,可编辑修改,欢迎下载交流。 Commit一条要3毫秒,所以也不能commit太频繁。 5.7 Insert和update速度比较 如果表内数据少,有索引,update要快 数据多,有索引,insert要快。 但还有看索引的多少,及update的字段,如果update不对索引及主键改变,速度很可能会比insert要快。 5.8 使用临时表取代一条一条插入 如果程序是要一条一条记录的插入到一个数据量很大的表中,如果是使用一个临时表作为一个中间表,先插入到中间表,再一次插入大表中。 我是用50个进程并行的,改动前后的速度比较是 50分钟--》4分钟。是分解的国泰君安深圳席位的数据,共9万条数据,137个席位。计算比较复杂。 改临时表后,锁的等待变得很少,数据库及cpu的压力就可以上去。 5.9 循环次数很多时注意减少执行语句(附例子) 下面是两个过程,可以比较一下 过程1: DROP PROCEDURE pr_test1 @ CREATE PROCEDURE pr_test1( OUT out_return_code INTEGER ) --返回值 LANGUAGE SQL Proc: BEGIN declare v_nobr_flag int default 0; declare v_fetch_brnext int; declare v_fetch_headnext int; declare v_error_flag char(1); declare v_error_desc char(1); declare m_br_branch_code char(1); declare m_br_sub_branch_code char(1); DoWork:BEGIN PFetch: while v_nobr_flag<100000 do set v_nobr_flag=v_nobr_flag+1; set v_fetch_brnext=0; set v_fetch_headnext=0; set v_error_flag,=??; 经典资料,WORD文档,可编辑修改,欢迎下载交流。 23 经典资料,WORD文档,可编辑修改,欢迎下载交流。 set v_error_desc=??; set m_br_branch_code=??; set m_br_sub_branch_code=??; end while PFetch; END DoWork; END Proc @ 过程2: DROP PROCEDURE pr_test2 @ CREATE PROCEDURE pr_test2( OUT out_return_code INTEGER ) --返回值 LANGUAGE SQL Proc: BEGIN declare v_nobr_flag int default 0; declare v_fetch_brnext int; declare v_fetch_headnext int; declare v_error_flag char(1); declare v_error_desc char(1); declare m_br_branch_code char(1); declare m_br_sub_branch_code char(1); DoWork:BEGIN PFetch: while v_nobr_flag<100000 do set v_nobr_flag=v_nobr_flag+1; values(0,0,'','','','') into v_fetch_brnext, v_fetch_headnext, v_error_flag, v_error_desc, m_br_branch_code, m_br_sub_branch_code; end while PFetch; END DoWork; END Proc @ 本人实验,pr_test1用时34秒,pr_test2用时15秒。 5.10 看程序执行时间及结果db2batch db2batch –d -zbdb –f test.sql –r test.res 有点像sybase的isql。 经典资料,WORD文档,可编辑修改,欢迎下载交流。 24 经典资料,WORD文档,可编辑修改,欢迎下载交流。 也有多个选项可以用,help。 5.11 看程序或语句具体的执行计划shell(改写后的语句) #goplan.sh #!/bin/ksh # [ $# -eq 1 ] || { echo \ exit } id=$1 output=${id}.out output2=db2exp.${id}.out1 set -x db2batch -d zbdb -f ${id}.sql -r ${output} -o o 5 e 1 db2exfmt -d zbdb -t -w -1 > ${output2} 5.12 两个表做join的不同方式的区别 这里几个例子是查询两个表中的记录有哪些在一个表中存在而在另一个表中不存在。 具体的执行计划可以用上面的goplan.sh来看。 以下是比较简单的方式,其实如果要核对的项很多,可能采用做两个cursor,排序后自己比较可能会更快。 5.12.1 Not in方式 select head.sub_branch_code, 0, '1', '总部有,营业部没有', '1', head.capital_account, head.account_head_type, head.account_branch_type from table( select * from kstar.tb_head_capital_account where branch_code='1104' and increment_flag<>'2' and (branch_code,sub_branch_code,capital_account) not 经典资料,WORD文档,可编辑修改,欢迎下载交流。 25
数据库管理系统DB2手册112页 - 图文(5)
2019-01-19 17:43
数据库管理系统DB2手册112页 - 图文(5).doc
将本文的Word文档下载到电脑
下载失败或者文档不完整,请联系客服人员解决!