sql与PB程序的优化.doc_第1页
sql与PB程序的优化.doc_第2页
sql与PB程序的优化.doc_第3页
sql与PB程序的优化.doc_第4页
sql与PB程序的优化.doc_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

微软用户第 15 页2020/3/20赢 sql与PB程序的优化 2009-01-13 09:09 748人阅读 评论(0) 收藏 举报 下面内容从CSDN的一篇贴子中找到的。我用过的一个优化方法是:当检索表和视图混合的查询时,若需要检索参数,且表与视图均可用于检索参数的话,应使用视图作检索条件,速度将有明显提升。 另附两篇关于 pb 代码优化的网摘: 优化你的 sql 和 dw 一、处理 SQL 语句 1、缓冲 SQL 语句 在应用程序中,有时需要反复调用同一组SQL语句,在这种情况下,可以通过在应用中为这些 SQL建立缓冲区来提高执行性能。在缺省情况下,SQL语句的缓冲区是关闭的,你可以通过如下语句打开它: SQLCACHE = n n 表示装入缓冲区的 SQL 语句数量(缺省为0)。 例如: dw_1.SetTransObject(sqlca) SQLCA.dbParm = SQLCache = 0 dw_1.retrieve() 如果将上例的 SQLCache = 0 改为 SQLCache = 25,此句的执行效率将提高五分之一左右。但应注意缓冲区的大小,否则也将影响程序执行的性能。 注:此方法对用 ODBC 和 ORACLE 连接的数据库非常有效。 2、捆绑变量 请看下例: SQLCA.DBPARM = DISABLEBIND=1 INSERT INTO DA_DH VALUES(1,河南0) INSERT INTO DA_DH VALUES(2,河南1) INSERT INTO DA_DH VALUES(3,河南2) INSERT INTO DA_DH VALUES(4,河南3) INSERT INTO DA_DH VALUES(5,河南4) INSERT INTO DA_DH VALUES(6,河南5) 这里未使用捆绑变量,再插入时 PB 将重新处理每个带有新值的SQL语句。 如果将上例改为: SQLCA.DBPARM = DISABLEBIND=0 INSERT INTO DA_DH VALUES(1,河南0) INSERT INTO DA_DH VALUES(2,河南1) INSERT INTO DA_DH VALUES(3,河南2) INSERT INTO DA_DH VALUES(4,河南3) INSERT INTO DA_DH VALUES(5,河南4) INSERT INTO DA_DH VALUES(6,河南5) 则系统将把 INSERT 语句按如下格式进行处理: INSERT INTO DA_DH VALUES(?,?) 其中 ? 称为占位符。系统性能将有所增强。 3、用数据窗口代替 SQL 语句 通常,为了获得某些数据,采用数据窗口和 SQL 语句都是可行的,但是PB 对数据窗口和 SQL 语句采用不同的处理机制,因此,具有不同的效率。 例:为里检索电话档案中的用户名,可以利用 SQL 语句,将所有的数据检索到一个多行编辑中,也可以检索到一个数据窗口中。 如果使用第一种方法: 首先定义一个游标: DECLARE CUR CURSOR FOR SELECT DA_DH.HM FROM DA_DH; 然后可以: STRING stxt,st int li open cur do li = li + 1 fetch cur into :stxtli ; st=st+stxtli + rn loop while stxtli close cur; mle_1.txt = st 也可以使用第二种方法: dw_1.settransobject(sqlca) dw_1.retrieve() 利用 POWERBUILDER PROFILER 工具进行检查,对比两种方法所需时间如下 方法 所需时间 (百分之一秒) SQL 语句 100.9857 数据窗口 49.0133 由于数据窗口或DATASTORE使用了标准的内嵌代码,而不是由开发人员进行全部编码,同时编译执行的速度比解释执行的速度快的多,因此在开发过程中应尽量使用数据窗口和DATASTORE.即使是必须用SQL语句的时候,也应该尽量将它们定义为存储过程(特别是在多用户的环境中),以提高应用程序的性能. 二、数据窗口的编程和执行 数据窗口是PB最值得被称道的, 其具有如下特点: 1. 多种显示方式. 2. 多种编辑方式. 3. 使用方法简单. 4. 具有多种报表形式. 5. 可实现屏幕滚动. 6. 可实现数据的有效性校验. 7. 执行性能显著提高. 8. 编程工作变少. 9. 可以在数据窗口内部实现数据哭的更新. 下面, 我将介绍一些用于提高数据窗口性能的技术. 1. 减少连接数据库的次数 连库操作是非常影响执行速度的操作. 因此在程序中,一旦与数据库连接后就应当尽量保持与数据库的连接, 减少连接数据库的次数.PowerBuilder 提供里两个函数来建立数据窗口与事务对象的连接: SetTrans() SetTransObject() 在程序中应当尽量使用 SETTRANSOBJECT(), 因为SETTRANS() 函数在每次调用 RETRIEVE(), UPDATE() 等函数之后, 都要执行数据库的连接和断开操作. 2. 下拉数据窗口与表的连接 对于数据库服务器来说, 表的连接操作是一项非常大的开销, 而 POWERBUILDER 提供的下拉数据窗口在某些情况下可以代替表的连接操作.例如, 为了在数据窗口上显示用户的电话号码和姓名:如果用表的连接的方法, 数据窗口对应的 SQL 语句应是这样的: SELECT DA_DH.DHHM,DA_HTH.DWM FROM DA_HTH, DA_DH WHERE (DA_HTH.DHHM=DA_DH.DHHM) 同样的程序可用下拉数据窗口来完成, 这里不再具体介绍.但是, 应当注意, 以上两种方法究竟哪一种数据更快, 与表的结构, 表的数量, 连接的方法等均有关系, 应当具体分析. 3. 共享数据 在一个应用程序中, 某些数据需要频繁的使用, 如果在每次使用时都从数据库中进行检索, 则需占用大量的服务器资源和网络资源. 为了减少开销, 可以在客户端对这些数据只进行一次检索, 然后允许其它任务共享这些数据. 例如, 如果有两个数据窗口, 都需要从第三方表中检索出用户的电话号码, 且此列用下拉数据窗口给出. 如果每次都对电话号码进行检索, 则性能较低. 因此, 可以单独建立一个关于电话号码的数据窗口. 在每次打开窗口时, 首先将电话号码检索到此数据窗口中, 然后另外两个数据窗口中关于电话号码的下拉数据窗口可以共享此数据窗口中的数据. 在窗口的 OPEN 事件中编写如下程序: dw_1.settransobject(sqlca) dw_2.settransobject(sqlca) dw_3.settransobject(sqlca) / 检索 dw_1 dw_1.retrieve() / 使 DW_2 的下拉数据窗口共享 DW_1 datawindowchild child1 dw_2.getchild(dhhm,child1) child1.settransobject(sqlca) dw_1.sharedata(child1) / 使 DW_2 的下拉数据窗口共享 DW_1 datawindowchild child2 dw_3.getchild(dhhm,child2) child2.settransobject(sqlca) dw_1.sharedata(child1) 使用这种方法, 避免了各个数据窗口间物理的拷贝数据, 因此减少了空间上的开销,提高了应用程序的综合性能. 4. 数据窗口间数据的拷贝 如果需要在数据窗口间共享数据, 应当尽量使用 SHAREDATA() 函数, 但是, SHAREDATA() 函数并不是物理地在数据窗口间拷贝数据, 如果在显示数据的同时, 还要对数据进行操作, 则需要进行数据的拷贝. 例如, 要求将 DW_1 中选定的行拷贝到 DW_2 中: 在窗口的 OPEN 事件中编程: dw_1.settransobject(sqlca) dw_2.settransobject(sqlca) dw_1.retrieve() 在数据窗口 DW_1 的 ROWFOCUSCHANGED 事件中编写下列程序: long lr lr = dw_1.selectrow(0,false) lr = dw_1.getrow() lr = dw_1.selectrow(lr,true) 要完成从 DW_1 到 DW_2 的拷贝工作, 有两种方法: 第一种: 在按钮 拷贝 的 CLICKED 事件中编程 long lr lr = dw_1.getselectedrow(0) dw_1.rowscopy(lr,lr,primary!,dw_2,100,primary!) 执行程序, 利用 POWERBUILDER PROFILER 得出所需时间为 1.7034(百分之一秒) 第二种: 在按钮 拷贝 的 CLICKED 事件中编程 dw_2.object.data = da_1.object.data.selected 执行程序, 利用 POWERBUILDER PROFILER 得出所需时间为 0.8062(百分之一秒) 5. 数据窗口属性的访问和修改 A. 数据窗口属性的访问 在程序中访问数据窗口的属性有下列几种方法: A1. 采用点表达式访问 A2. 应用多个独立的 DESCRIBE() 函数访问 A3. 只使用一个 DESCRIBE() 函数, 采用复合参数访问多个属性 上面三中方法, 通常第一种方法最慢, 第三种方法最快. 例如: 在窗口的 OPEN 事件中 DW_1.SETTRANSOBJECT(SQLCA) DW_1.RETRIEVE() 第一种方法: 在检索按钮的 CLICKED 事件中编程. string dx, dy, dh, dw dx = dw_1.object.da_dh.x dy = dw_1.object.da_dh.y dx = dw_1.object.da_dh.height dy = dw_1.object.da_dh.width st_1.text =dx+,+dy+,+dh+,+dw 第二种方法: string dx, dy, dh, dw dx=dw_1.describe(da_dh.x) dx=dw_1.describe(da_dh.y) dx=dw_1.describe(da_dh.height) dx=dw_1.describe(da_dh.width) st_1.text =dx+,+dy+,+dh+,+dw 第三种方法: string dx, dy, dh, dw st_1.text=dw_1.describe(da_dh.x +& da_dh.y +& da_dh.height +& da_dh.width) 实验证明, 第三种方法的速度是最快的. 但是程序的可读性最差. B. 数据窗口属性的修改 在程序中修改数据窗口的属性有下列几种方法: A1. 采用点表达式修改 A2. 应用多个独立的 MODIFY() 函数访问 A3. 只使用一个 MODIFY() 函数, 采用复合参数访问多个属性 上面三种方法, 通常第一种方法最慢, 第三种方法最快. 例如: 在窗口的 OPEN 事件中 DW_1.SETTRANSOBJECT(SQLCA) DW_1.RETRIEVE() 第一种方法: 在检索按钮的 CLICKED 事件中编程. DW_1.SETREDRAW(FALSE) dw_1.object.da_dh.x = 18 dw_1.object.da_dh.y = 16 dw_1.object.da_dh.height = 100 dw_1.object.da_dh.width = 200 DW_1.setredraw(true) st_1.text =dx+,+dy+,+dh+,+dw 第二种方法: DW_1.SETREDRAW(FALSE) dw_1.modify(da_dh.x = 18) dw_1.modify(da_dh.y = 16) dw_1.modify(da_dh.height = 100) dw_1.modify(da_dh.width = 200) dw_1.setredraw(true) 第三种方法: dw_1.modify(da_dh.x=18 +& da_dh.y=16 +& da_dh.height=100 +& da_dh.width=200) 实验证明, 第三种方法的速度是最快的. 但是程序的可读性最差.注意, 在方法一和方法二中, 都使用的 setredraw() 函数以减少屏幕的重绘, 否则, 执行速度将严重下降. 6. 数据窗口中数据的访问 在程序中, 经常会需要动态的修改数据窗口中的数据. 对此, PB 提供了多种方法, 各种方法在性能上会有一些差异. A. 数据窗口中数据的访问 目的: 将数据窗口中的电话号码存放在一个数组中.请比较下面两中方法. 方法一: string da_dh long ll,i ll = dw_1.rowcount() for i = ll to 1 stet -1 da_dhi = dw_1.getitemstring(i,dhhm) next 方法二: string da_dh da_dh = dw_1.object.dhhm.current 测试发现, 第二种方法比第一种方法快将近一倍. 数据量越大这种差异越明显. B. 数据窗口中数据的修改 目的: 修改数据窗口中的电话号码列的值. 请比较下面两中方法. 方法一: dw_1.setitem(i,dhhm,l_name) 方法二: dw_1.i = l_name 测试发现, 第二种方法比第一种方法快将近一倍. 数据量越大这种差异越明显. 7. 数据窗口事件对性能的影响 对于数据窗口控制中经常发生的事件, 应当尽量减少其中的程序代码. 特别是如下事件: a. itemchanged b. editchanged c. itemfocuschanged d. pbm_dwnkey e. rowfocuschanged f. retrieverow 在这些事件中的任何处理程序, 都会降低应用程序的处理速度. 所以应当尽量减少这些事件中的处理程序, 必要时, 可以考虑只将重要的代码放在这些事件中, 而将剩余的代码放在一个传递的事件中. 例如,如果需要用到数据窗口的 ROWFOCUSCHANGED 事件,可以为数据窗口定义一用户事件 UE_RE,而在数据窗口的 ROWFOCUSCHANGED 事件中写如下代码: PARENT.postevent(ue_re) 在 UE_RE 事件中再编写相应的程序代码,如: string code dw_1.selectrow(0,false) dw_1.selectrow(rownum,true) code = getitemstring(dw_1,rownum,dhhm) dw_2.retrieve(code) 另外, 为了获得当前行号,应尽量使用数据窗口的 CURRENTROW 变量,而少用 GETROW() 函数。 8. 数据窗口的列名称与列编号 对数据窗口的某列进行访问, 可以采用该列的名称, 也可以使用该列的编号。 例如: 采用列编号: dw_1.object.datall_row,2 dw_1.getitemstring(3,2) 采用列名称表示某列: dw_1.object.article_textll_row dw_1.getitemstring(3,dhhm) dw_1.setitem(3,date,1999-03-31) . 对于以上两种方法,如果只进行一次查询,在速度上并没有太大的区别,如果需要循环访问数据窗口上的某一列,则速度上的差异就表现的比较明显,采用第一种方法要快, 但是程序的可读性比较差。但是,在使用函数时(如 GETITEM() 和 setitem() ), 执行速度往往没有很大差别。 9. 计算域 数据窗口的计算域会对数据的操作性能产生影响。 如果数据窗口中包含许多复杂的计算域,将严重影响数据窗口的执行速度。 - 条件和循环类语句的优化 现今计算机的运行速度已经很快了,并且由于老板时常在耳边念着紧箍咒,因此,我们有意或者无意的忘记优化我们的代码,只要能完成任 务就行了(我也是)。不过,我们闲下来的时候,不妨也来看看我们的代码是否有需要改进的地方。下面就是我觉得值得优化的几种情况。 第一种情况: IF condition1 AND condition2 THEN /Code goes here. END IF 和 IF condition1 THEN IF condition2 THEN /Code goes here. END IF END IF 对于书写的第一种方式,由于PB编译方式与常见的方式不同,就是无论条件1的值如何,都要对条件2进行运算。这样一来,当条件1为false 时,就可能要无谓的对条件2进行运算了。就按随机的概率而言,可能会多进行一半的运算。因此,对于大多数情况而言,我想最好是以第二 种方式书写。当然,特殊情况也是有的,那就是你的确想对条件2进行运算。类似地,对于or也一样。 IF condition1 OR condition2 THEN /Code goes here. END IF 和 IF condition1 THEN /Code goes here. ELSE IF condition2 THEN /Code goes here. END IF END IF 第二种情况: IF NOT condition THEN /Code goes here. END IF 和 IF condition THEN /No code goes here. ELSE /Code goes here. END IF 对于上一种方式,条件表达式返回false并且再进行一个非运算,才执行下面的代码。这样相对于下面一种书写方式可能多执行了一个非运算 。如果大家有什么疑问,您不妨测试一下下面这个例子: /小测试:其中的判断条件只是为了表示一下,实际情况可能更复杂。 long i /计数器 long ll_start /执行开始时间 long ll_used1 /方式一耗时 long ll_used2 /方式二耗时 /方式一 ll_start = Cpu() for i = 1 to 900000 if not (1 1) Then i = i end if next ll_used1 = Cpu() - ll_start /方式二 ll_start = Cpu() for i = 1 to 900000 if 1 1 Then else i = i end if Next ll_used2 = Cpu() - ll_start

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论