分类: DB2/Informix
2011-08-15 10:54:19
INFORMIX数据库是一被广泛应用的关系型数据库,如何提高其应用性能是大家关心的话题,特别是随着库中数据量与应用处理交易量的不断增多,其运行效率问题尤显突出。除了充分应用INFORMIX新品质,从INFORMIX-SE到INFORMIX-ONLINE高版本外, INFORMIX数据库的运行效率与其系统参数(online)的配置、性能的调整、库表创建的方式、索引的策略、ESQL/C程序的质量优劣直接相关。本文结合工作实践介绍以下提高 INFORMIX数据库运行效率的若干优化策略与措施。
一、 INFORMIX系统性能参数优化
系统性能与磁盘、CPU、共享内存和网络相关。对磁盘调整的原则是降低读盘次数,极大化每次读盘数据量,数据分布均匀,防止瓶颈的发 生。Online的磁盘空间应采用裸设备方式(raw
device),而不采用文件系统方式(cooked file),前者比后者处理速度要快得多,且可靠性 高。物理日志缓存空间应在30~50兆间即可,不必太大。设置cpu
vp个数为cpu个数减1(若cpu个数为1,则cpu vp也为1)。共享内存一般是系 统内存的1/3~1/4,一个cpu vp配4个LRU队列,n个
LRU队列配n个页刷新进程page_cleaner,调谐使其高速缓冲区读命中率大于95%,写命中率大于85%,设定多张网卡可改进性能,网络碰撞率应在8%以内。系统核心参数按informix各版本提出的配置要求调整即可,若调整不对,在构造online时即可能不会成功。Informix-online数据服务器性能的调试往往在一定的经验值基础上动态反复调整、测试才能获得最终满意的结果。INFORMIX数据库系统参数性能调整的优劣直接影响INFORMIX数据库运行效率,对其性能调整的具体方法与步骤,informix资料有较详 尽说明,这里不作重点讨论。
二、 创建库表方式优化
1.数据库建库程序对每个数据表空间分配的优化。
在建表前将数据库每张表数据量大小作一估算,以便将表的第一个“extent”(物理上连续的页)空间分配尽量和估算值大小一致,下一 个“extent”空间分配则根据表数据的增加量估计值来分配,这样可减少数据分配碎片和空间浪费,提高数据库系统的效率。
2.引入表分割fragmentation,使数据在物理逻辑上分布均匀,有助于并行处理性能的提高。
3.建表时对表的记录锁方式根据应用处理的不同区别对待。批量处理的表采用页锁(page)方式,实时交易的表采用行锁(row)方式。锁方式可 以在建表时确定,也可以用alter
tabname lock mode(row)和alter tabname lock mode(page)命令改变。值得注意的是通过 dbimport、dbexport转移生成的表其默认锁方式是页级锁,对于实时交易且操作频繁的表应改为行级锁方式,使用oncheck -pt命令可查得表 的锁方式状态。
4.建库的日志方式:
(1)No logging:不能进行事务处理。
(2)buffered log:共享缓存满即刷新写入磁盘。
(3)unbuffered log:当一个交易完成时即刷新写入磁盘。
(4)ansi mode:只有日期格式差异,月日年形式,其他与unbuffered相同。
一般我们对实时处理系统日志方式采用unbuffered log,在进行大批量数据集中装卸时采用no logging。如:
create database workdb in dbspacel with log;
create table satmx(
zh char (20),
rq date,
fse money(16),
ye money(16)
)
in dbspacel
EXTENT size 1024
NEXT size 64
LOCK mode (row);
Greate index satmx_idx on satmx(zh,rq);
Alter table satmx modify next size 128 lock mode (page);
Alter index satmx_idx to cluster;
三、 应用程序的优化
1.Select语句优化要点
(1)对于大数据量的求和应避免使用单一的sum命令处理,可采用group by方式与其结合,有时其效率可提高几倍甚至百倍。例如,银行常要进 行帐户的总帐与明细帐一致性核对(总分核
对),数据量大,原采用单一的sum命令与while语句结合来完成,现改用以下group by方式后效率 大相径庭。
/*将定期表中所有数据按机构,储种统计户数,余额置临时表中并建索引*/
select zh[1,9] jg,zh[19,20]cz,count(*)hs,sum(ye)sumye
from satdq
where bz=″0″
group by zh[1,9],zh [19,20]
into temp satdq_sum;
create index satdq_suml
on satdq_sum(jg,cz);
(帐号zh的前9位为机构编码,第19至20位为储种)
(2)最具有限制性的条件放在前面,大值在前,小值在后。
如:where col<=1000 and col>=1 效率高
where col>=1 and col<=1000 效率低
(3)避免子查询与相关查询。
如:where zh in (select zh from table where xm matches ″*11*″)
可将其编为declare cursor 的一while循环来处理。
(4)避免会引起磁盘读写的rowid操作。在where子句中或select语句中,用rowid要产生磁盘读写,是一个物理过程,会影响性能。
如原为:
declare ps2 cursor
for
select *,rowid
into b,id
from satmxhz
where zh[1,9]=vvjgbm
and bz=″0″
order by zh;
open ps2;
fetch ps2;
while (sqlca.sqlcode==0){
……
update satmxhz
set
sbrq=b.sbrq,
ye=b.ye,
lxjs=b.lxjs,
wdbs=wdbs+1,
dac=dac
where rowid=id;
……
fetch ps2;
}
改为:
declare ps2 cursor
for
select * into b
from satmxhz
where zh [1,9]=vvjgbm
and bz=″0″
for update of sbrq,ye,lxjs,wdbs,dac;
open ps2;
fetch ps2;
while (sqlca.sqlcode==0){
……
update satmxhz
set
sbrq=b.sbrq,
ye =b.ye,
lxjs=b.lxjs,
wdbs=b.wdbs,
dac=dac
where current of ps2;
……
fetch ps2;
}
(5)where子句中变量顺序应与索引字键顺序相同。
如:create index putlsz_idx on putlsz(zh ,rq,lsh)
索引字键顺序:首先是帐号zh,其次是日期rq,最后是流水号lsh,
所以where子句变量顺序应是where zh=″11111″and rq=″06/06/1999″and lsh<1000,不应是where
lsh<1000 and rq=″06/06/1999″ and zh =″11111″等非索引字键顺序。
(6)用=替代matches的操作。
如:where zh matches ″330678860*″应用where zh[1,9]=″330678860″替代。
(7)通过聚族索引cluster index提高效率。
(避免使用order by,group by,该操作需生成临时表而影响效率,可用视图来处理,视图的引入能控制用户的存取,提高效率。
(2)避免加长锁、长事务操作,这在处理大数据量时其优劣尤为突出,在能保证数据一致性的前提下应将长事务分解为小事务来处理。 四、 index索引策略的优化与原则 (3)数据库在做″dbimport″后应运行update statistics语句。 |