论文导读::该系统采用的是非物化视图。存储过程优化。通过优化重构提高信息系统资源响应率。
论文关键词:资源响应比,程序代码重构,非物化视图,存储过程,XML解析
0 引言
信息系统的响应速度,如果光依靠提高硬件配置(如增加CPU数量、扩大内存、提高存储和交换设备的性能等)来实现,从效率上看未必合理。
系统资源响应率作为信息系统效率评价的重要指标,是指在一定的信息资源配备下的系统响应速度。影响该项指标的主要因素包括:信息系统的整体架构设计、数据结构设计、应用软件程序代码效率以及数据库和应用中间件等系统软件的优化配置情况等。
本文针对浙江某石化企业管理信息系统,以多层次软件优化重构为主要手段,来实现提高信息系统资源响应率。
1 信息系统现状与问题
该信息系统主要功能是实现销售管理、生产管理、一体化办公等企业综合信息管理。系统开发完成运行五年多来,随着数据量的不断增加,系统运行越来越缓慢,一些业务的办理已经慢到了难以忍受的地步。为此资源响应比,企业首先第一步考虑的是更换升级服务器小型机,更换后,系统运行速度虽然有所加快,但效果并不明显。因此,我们提出对该系统进行梳理和分析,找出影响系统性能的关键问题和瓶颈,解决软件速度慢的根本问题。通过跟踪信息系统的运行,针对信息系统中订金、合同办理、查询统计、提交等业务效率低下的问题,从系统架构、数据库设置、数据结构、程序代码等多个方面进行调整和优化。由于篇幅所限,本文选取了其中数据库视图优化、存储过程优化以及表结构和相关代码优化等几个典型过程。
2 数据库视图优化
2.1问题描述
该系统采用的是非物化视图,非物化视图在每次查询时都需要做一次表联接。因此,视图创建语句的好坏直接影响到查询的性能论文范文。通过分析发现,服务器端的不少视图在创建时没有考虑到将来表的膨胀趋势,没有遵照一定的优化准则,导致视图查询的效率随着数据量增加逐渐降低。由于视图经常要被作为查询对象,因此大大影响了系统性能。
2.2通过视图优化提高性能
以其中一个视图物料交换情况为例。该视图每次打开就需要20秒以上的时间。分析该视图的执行计划发现:Oracle先是对一些表进行索引扫描,根据不同条件取得相应表中的行ID,并存放在内存中。但是当最后扫描表T_GOODS时出现了问题。由于在创建语句中,T_GOODS处于联接表的最后位置资源响应比,也就是Oracle将把这张表作为驱动表,最先作联接。此时,系统会做如下几件事:
(1)对T_GOODS做全表扫描,T_GOODS共有大约70万条记录;
(2)根据联接条件取得符合条件的行ID;
(3)将这些记录和其他表依次作联接。
由此可见,代价主要集中在两点,一是全表扫描的代价;二是作联接的代价。全表扫描70万条记录约需10秒。另外在创建语句中T_GOODS表上并没有条件限制,因此做联接的记录数也将会有70万条,所以联接的代价是巨大的。
那么如何减小这些代价呢?经过分析发现该视图由5张表联接而成,其中表T_GOODSORT要和多张表做联接,大小仅为9千多条记录,如果将这张表作为驱动表,不仅减少了全表扫描的时间,更加节约了表联接的时间代价。
通过优化更改视图创建语句,将表T_GOODSORT作为驱动表。
经过测试,优化后打开该视图耗时仅1-2秒,提高性能约10倍以上。
此类问题解决方案为:逐一分析数据库端视图,尤其是那些常用到的、由多张大表联接起来的视图。按照上述方法进行优化。
3 存储过程优化
数据库端的优化,除了上述的视图优化,还包括为常用表创建索引等。创建索引不会影响原来的程序逻辑资源响应比,但可明显加快相应的查询速度。另外,对存储过程的优化也是至关重要的。理想的存储过程优化方法是通过改变联接顺序,不改变联接结果和程序逻辑,在不影响业务模块的条件下提高性能。
以查询历史库的存储过程为例。原代码如下:
INSERT INTO T_INVOICEINFO(ID,USER_NAME,USER_ID,CERTID,GOODSNO,ADDR,CERTNO, GOODSCODE,SITE,MAKETIME)SELECT INID,OWNER,OWNER_CODE,CERT_ID,GOODS_NO, ADDRESS, CERT_NO,GOODS_CODE, ‘历史库’,BIRTH_DAY FROM V_HISCERTSALLB WHERE EXISTS ( SELECT CERT_ID FROM T_HISSHARECERTS A WHERE SHARE_CID IN(INUSERID,INC_USERID) AND A.CERT_ID=B.CERT_ID);
上述SQL语句中采用了EXISTS谓词。通过分析该SQL语句执行计划发现,该语句有上百万次数据量交互,磁盘读写也达到上万次,非常耗时。从操作步骤可以看出,SELECT CERT_ID FROM T_HISSHARECERTS A WHERE SHARE_CID IN(INUSERID,INC_USERID)这一语句选出来的结果被放到了NESTED LOOP的循环外层。也就是说,先选出V_HISCERTSALL中的所有数据,然后再和T_HISSHARECERTS选出来的记录进行逐一比对,而因为从T_HISSHARECERTS选出的记录非常少(一般小于10条),因此大部分数据被剔除了,造成前面表联接很大程度的浪费论文范文。这是EXISTS写法的一个特点,先做EXISTS外的部分,再和EXISTS里面的部分逐一比对。显然,这不是我们想要的结果。
因此,优化改写此段语句,把范围最小的条件:WHERE SHARE_CID IN (INUSERID,INC_USERID)放到循环内层最先做。这样之后的表联接都会基于这个结果集。最简单的方法就是用IN语句来改写。更改优化后如下:
INSERT INTOT_INVOICEINFO (ID,USER_NAME,USER_ID,CERTID,GOODSNO,ADDR,CERTNO,GOODSCODE,SITE,MAKETIME) SELECT INID,OWNER,OWNER_CODE,CERT_ID,GOODS_NO,ADDRESS, CERT_NO,GOODS_CODE, ‘历史库’,BIRTH_DAY FROM V_HISCERTSALL WHERE CERT_ID IN (SELECT CERT_ID FROM T_HISSHARECERTS WHERE SHARE_CID IN (INUSERID,INC_USERID) );
分析改写后SQL语句执行计划可以发现,数据量交互降到了几百次资源响应比,而磁盘读取次数也只有两百多次,大大改善了性能。
4 表结构优化
表结构优化的复杂性在于除了对表本身的优化重构外,还要进行相关存储过程及程序代码等的改动。通过分析发现原系统部分表结构设计的不合理,特别是使用频率高、数据量大的合同文档表结构设计不合理,导致在每次翻页时都需要进行一次数据库读操作与若干次数据库写操作,大大影响了系统的响应速度。要减少数据读取次数,需要对表结构进行平面化处理优化,即采用XML描述合并一些经常同时存取的字段。
4.1数据库端更改
(1)表结构重构
当前系统的各类合同文档主要保存在WEB_DOCINFO,WEB_DOCINFO_TEMP,WEB_DOCINFO_HIST三张表中。其中第一张是工作表;第二张是暂存表;第三张是历史表,工作表中的任何内容在修改前,原有合同内容都会转入历史表。三张表的结构是相同的,基本定义如下:
FLD_INDEX 记录编号
PRJDOC_INDEX 合同项目编号
GOODS_NO 货物内码
DOC_TYPE 文档类型
FLD_NAME 合同字段名
FORM_INDEX 合同字段索引值
FLD_VALUE 合同字段内容
这张表在设计上不符合关系数据库第二范式(2NF)。一个文档记录仅作为合同文档中一项的内容。在这种表结构下,更新或增加一份合同,要进行上百次的sql操作。作为系统的主表之一,这样的设计造成了大量的数据冗余,导致系统性能的严重下降,并可能带来数据更新不一致。
解决这一问题的方法就是重新设计表结构,使得每份合同文档对应数据库表中的一条记录。由于各种合同的合同项是不相同的资源响应比,一份标准的合同文档涉及的合同项多达100项以上,所以将每一个合同项单独定义为表的一个字段是不可行的。优化设计的方案是将一份合同文档的所有项以XML的形式保存在一个BLOB字段中。这样的设计基于以下考虑:
① xml是一种通用的格式,有很好的可移植性与可读性;
② 由于每份文档的合同项有差异,正好可利用xml很好的灵活性。
依据该设计方案,合同表的SQL定义为:
CREATETABLE WEB_DOCINFO
( FLD_INDEX NUMBER(15,0)NOT NULL,
PRJDOC_INDEX VARCHAR2(9),
GOODS_NO NUMBER(10,0),
DOC_TYPE NUMBER(8,0)
DOC_CONTENT BLOB,
CONSTRAINTPK_WEB_DOCINFO PRIMARY KEY (FLD_INDEX)
)
DOC_CONTENT字段中保存了合同内容的xml文档,格式如下:
<htinfo>
<fieldid=’field1’>
<fld_name>合同项名称</fld_name>
<fld_value>合同项内容</fld_value>
</field>
<fieldid=’field2’>
…
</field>
…
…
</htinfo>
(2)存储过程重构
存储过程重构分为两类,一类是涉及到合同项这一级别(FLD_NAME,FLD_VALUE),需要改动;另一类操作都是在合同这一级别,没有涉及到合同项这一级别(FLD_NAME,FLD_VALUE),这样的存储过程在表结构更改后无需做改动。
1/2 1 2 下一页 尾页 |