如何提高Visual FoPro的性能

时间:2022-10-08 04:08:00

如何提高Visual FoPro的性能

摘要:本文介绍一些实用技巧和技术。如果我们能正确地应用这些技术,就可以大大改进VisualFoxPro的性能,提高数据的访问速度。

关键词:VisualFoxPro;性能;技术

高性能是MicrosoftFoxPro数据库管理系统(特别是它的数据库引擎)的最大特点。Visual

FoxPro关系型数据库引进了对象模型,提高了引擎的存取速度并增强了客户/服务器特性,因此整个管理系统的功能变得更加强大。但是,这些强大功能的代价是使管理系统变得更加复杂。因此,一方面,很容易开发出性能稳定、面向对象、使用远程数据的应用程序,另一方面,也很难避免出现低性能的应用程序。

本文从改善、提高VisualFoxPro性能的目标出发,介绍一些实用技巧和技术。

一、改善本地数据访问的性能

1.使用索引

Visual

FoxPro中的索引是基于树的数据结构,因此查询经过索引的表是很快的。但当表中有较多的索引时,更新表和向表中输入数据就会变得慢一些,因为

VisualFoxPro需要更新每个索引。通常,只需在用于筛选和联接的数据上建立索引。

应该避免以FOR<条件>或NOT<条件>这样的形式建立索引表达式,因为这些表达式无法优化。例如:INDEXONDELETED

()TAGDEL是可以进行Rushmore优化的,但是,INDEXONNOTDELETED()TAG

NOTDEL则不能。在特殊情况下,我们不想包含被删除的记录,可以先设置SETDELETEDON,再创建索引,这样可以加速操作。

此外,注意不要在那些只有少数离散数据中取值的字段(例如逻辑型字段)上建立索引。

2.优化查询的条件

VisualFoxPro通过查找与筛选表达式左边相匹配的索引表达式来优化筛选条件。我们经常试图将索引的标识名与一个筛选表达式相匹配,而

VisualFoxPro无法通过这种方式优化查询。下面使用的索引是错误的:

USECUSTOMERS

INDEXONUPPER(cu_name)TAGname

SELECT*FROMcustomers;

WHEREcu_name="BILL"&&notoptimized.Noindexon"cu_name"

在一个筛选的查询中正确使用索引的方法是∶

SELECT*FROMcustomersWHEREUPPER(cu_name)="BILL"&&Optimized!

3.使用SYS(3051)函数

SYS(3051)S函数控制从一个记录(表、索引或备注文件)的锁定失败到再次尝试锁定它之间的时间间隔,以毫秒为单位,默认值为333

毫秒。

如果在我们的系统中存在大量的锁定竞争,可以将这个值调大(最大值为

1000),以提高我们应用程序的性能,因为应用程序不会因徒劳锁定记录而浪费时间。但是,如果锁定竞争不多,应将该值调小(最小值为

100),以加速记录锁定的尝试。

4.注音标记和机器排序序列

在VisualFoxPro

中,已经改进了查询包含国际化字符(带有区分标记的字符)数据的优化方式。但如果我们的索引表达式的结果包含的字符都不带注音标记(例如B或

M),则查询还能更快。

非机器排序序列(例如“通用”排序序列)比机器排序序列慢,有下列几个原因:非机器索引关键字的大小是机器索引关键字的两倍,因为必须为每个字符记录注音信息;为了返回正确的结果,非机器排序序列要使用很多特定的规则来断定索引的顺序。因为机器排序序列更快,所以它通常用于联接和查找,而其他排序序列用于排序记录。

5.使事务安排紧凑

事务应该只包含更新数据操作,在事务中包含其他任何操作(如使用我们界面,使用编程结构的CASE、WHILE或IF

语句)都会降低更新数据的效率。

这对于VisualFoxPro

是很重要的,因为使用事务需要锁定记录。在事务中以及更新记录时会锁定记录,并且在提交或回滚事务之前不会释放这些锁定的记录。即使我们使用了RLOCK

()或FLOCK(),然后执行UNLOCK,记录在ENDTRANSACTION或ROLLBACK

语句之前也一直保持锁定。另外,在追加记录时需要VisualFoxPro

锁定标头(即其他我们可以修改,但不能添加或删除),并且在事务结束(提交或回滚)之前一直锁定标头。因此,在一个高容量多我们的系统中,减少锁定记录的时间就变得很关键。

6.使用新的数据类型

在VisualFoxPro

中引入了四种新数据类型∶日期时间型、整型、双精度型和货币型。所有这些类型的数据都以二进制数据的形式保存在磁盘上(整型是四字节的二进制数据,其他数据类型是八字节的二进制数据)。

使用这些数据类型有两个优点:首先,由于在磁盘上保存数据时所占的空间更小(一个八位数的数据若用数值型保存将占用八个字节,而保存为整形只需要四个字节),这样,从磁盘向内存加载数据和索引时,一次可以加载更多的有用数据,从而提高应用程序的性能。第二个优点是不需要任何的数据转换。Visual

FoxPro内部将整型数据表示为四字节的二进制值,而数值型数据在磁盘上保存为ASCII码形式,因此,在每次读数据时,都必须将ASCII

码转换为二进制值,存盘时再转换回去。由于整型和双精度型数据(以及日期型和货币型数据)不需要这种转换,所以数据访问就更快。

在新数据类型中,整型数据对速度的影响最大。要尽量使用整型数据作为主关键字和外部关键字的值。这样可以得到更小的DBF

文件,更小的索引,更快的连接。

二、提高远程数据访问的性能

在任何后端数据库中检索数据是很费时的。为了加快数据的下载(或更新),可使用下面的方法。

1.只下载需要的数据

在一个应用程序的功能单元(比如,表单或报表)中,很少需要访问表中的所有数据。通过创建远程视图,只得到(或更新)我们需要的字段和记录,就可以减少通过网络的数据数量。例如,在我们的表单上有四个控件,分别绑定了远程视图的字段(客户标识号、公司名、联系人和来自客户表的地址),可使用SELECT

customer_id,company,contact,addressFROMcustomersSELECT则会好得多。

2.使用一个WHERE子句

为了进一步限制下载(或更新)的数据数量,可以使用WHERE子句。对于上面的示例,如果我们只需要西南部的客户记录,我们视图的SELECT

语句可以是:

SELECTcustomer_id,company,contact,addressFROMcustomers

WHEREregion=''''NORTHWEST''''

VisualFoxPro提供的视图灵活性以及SQLPassThrough技术使我们可以在SELECT、UPDATE和

DELETE等SQL语句的WHERE子句中使用参数。例如,对于上例,我们可以使用参数在运行时刻下载任何地区的信息:

SELECTcustomer_id,company,contact,addressFROMcustomers

WHEREregion=?pcRegion

式中,“pcRegion”是参数的名称。

3.使用正确的更新条件

视图设计器中的“更新条件”选项卡允许我们指定视图中的数据如何被更新(插入和删除)。在选项卡中的“SQLWHERE

子句包括”部分,我们可以控制UPDATE和DELETE操作中WHERE

子句的内容。这对于在后端控制数据冲突是很关键的,对于改善性能也是很重要的。

因为我们向后端更新的字段总是可更新字段的子集(并且一定是视图中字段总数的子集),在大多数情况下都使用“关键字和已修改字段”选项。对于支持时间戳的服务器数据库,建议使用“关键字和时间戳”设置,这种更新方式比用“关键字和已修改字段”更快。

4.使用BatchUpdateCount属性

有些服务器(例如MicrosoftSQLServerServer)允许我们在一个单独的数据包中发送一批SQL

语句,这个技术加速更新、删除和插入,因为通过网络传送的网络包的绝对数量减少了,而且服务器数据库可以成批编译多个语句而不是单独编译。

我们应该对于这个属性和PacketSize

属性用不同的值来试验,以优化我们的更新。可以在“查询”菜单的“高级选项”对话框中设置该属性,或者通过DBSETPROP()或

CURSORSETPROP()函数来设置。注意若要使用这个属性,必须通过调用DBSETPROP()或SQLSETPROP()

函数设置“Transactions”属性来启动人工事务。

5.使用PacketSize属性

PacketSize属性控制向数据库服务器传送和下载的网络包的大小(按照字节)。它实际上是由ODBC

设置的,并且可以是任何非零值。不同的网络对该属性有不同的处理,因此我们应该参阅网络服务文档。该属性的默认值是4096

字节。如果我们的网络支持更大的数据包,我们可以在每次请求(SELECT、INSERT、UPDATE、DELETE)

时将该属性值增加以加大网络吞吐量。

6.使用FetchMemo属性

FetchMemo属性控制当从后端取得一个记录时是否也取得备注和二进制(通用字段)数据。请将该属性设置为

.F.,这样,直到真正需要时,才从网络传递数据,从而提高我们的查询取得数据的速度。

7.在本地机上保存查阅表

在很多情况下,我们的应用程序经常访问只读数据。例如,我们的应用程序可能会经常使用一个包括各个公司人员的档案表,将这些数据保存在本地机上(也就是,不把这些表装在服务器上),查询会更快。对于从不更改或很少更改的数据,这个技术会很有用。

8.使用本地规则

几乎很少有人知道,VisualFoxPro

在本地和远程视图中也支持字段级和记录级规则。这些规则是为了防止与数据或商业规则不符的数据进入数据库。可以将这些规则放在视图中,而不仅仅放在后端表中,这样作的好处是:在无效数据通过网络传送之前就可捕获它。缺点是:这些规则并不自动与后端服务器表上的规则相匹配。因此,如果后端表规则更改了定义,必须人工更改本地定义的视图中的规则。但是,如果规则很简单,这也不是一个很大的负担。另外,规则定义并不经常改变,因此我们也不必担心会经常更新本地的规则。

三、改造表单对象性能

1.使用数据环境

在“表单设计器”或“报表设计器”中使用数据环境,则打开表和在表间建立关系的速度会比在表单的Load事件中使用USE、SETORDER

和SETRELATION命令快得多。这是因为VisualFoxPro使用底层的系统调用来打开表并建立索引和关系。

2.限制表单集中表单的数目

只有在必须让一组表单共享一个私有数据工作期时才使用表单集。当我们运行一个表单集时,即使只显示了表单集的第一个表单,VisualFoxPro

也会创建表单集中所有表单和所有表单中的所有控件,这样很费时间。如果表单不必共享一个私有数据工作期,这样做是不必要的。我们应该建立独立的表单并在需要它们时执行

DOFORM命令。

当然,如果使用了表单集,在访问表单集中的表单时也会得到些好处。因为所有表单已被加载到内存中了,只是没有显示,所以显示表单会比较快。

3.向页框中动态加载页面控件

与表单集类似,当加载页框时,也加载了每个页面上的所有控件,从而降低了性能。我们可以创建页框中每个页面上控件的类来解决这个问题。使用这个技术,由于直到访问时才加载页框中第二及其他页面上的控件,所以可以加速表单的加载。

4.动态绑定控件与数据

对于一个包含很多与数据绑定的控件的表单,如果我们将绑定的时间延迟到需要的时候,也可以极大地提高表单的性能。

我们可以将表单使用的表和视图放在数据环境中,这样当加载表单时表和视图就打开了。然后,当一个控件(例如组合框)获得焦点时,我们可以将控件与数据值绑定。

5.使用LockScreen属性

任何对表单上控件的更改,这个属性允许我们延迟屏幕刷新。例如,使控件可见或不可见,更改控件颜色,或者在绑定型控件中移动记录,都可以用这个属性将它们延迟到所有更改都结束时再刷新,这样系统的效率会更高。

6.在视图中使用NoDataOnLoad属性

视图的数据环境临时表对象的NoDataOnLoad属性与视图的USE命令的NODATA

子句的作用相同。它打开视图,但是视图不取得任何数据。对于本地和远程视图都是如此。例如,我们有一个有关客户信息的表单,它使用一个包含客户信息的视图,该视图使用参数代替

customer_id的具体值。我们可以输入一个有效的customer_id,然后按下“搜索”按钮。

这样做的优点是表单的加载时间大大减少了,因为视图不给我们带来任何数据,但是与视图字段绑定的控件仍是绑定的,因为存在一个打开的工作区(只是其中没有数据)。

四、完善OLE的性能

在访问OLE数据之前先运行OLE服务程序。如果与通用字段数据类型相应的服务器(例如MicrosoftExcel或

Word)在客户机的计算机上已经运行了,则与通用字段绑定的控件通常会获得更好的性能。

1.自动化的性能

在某些情况下,即使已经运行了一个实例,OLE服务器(例如Microsoft

Excel)仍然经常启动另一个新的实例。要想改变这种情况(并提高性能),请使用GetObject函数而不要使用CreateObject

函数。例如,下面的调用:x=GetObject(,"excel.Application")总是使用一个已存在的实例,但是,x=

CreateObject("excel.Application")将创建一个新的实例。

如果我们调用了GetObject()函数,而服务器还没有运行,系统会返回一个错误。我们可以俘获这个错误并在错误处理程序中调用

CreateObject()函数。

2.不使用MEMLIMIT

VisualFoxPro不能识别MEMLIMIT。在FoxPro中,MEMLIMIT是一个配置设置,指定FoxPro

分配供自己使用的最大内存数。不要使用这个配置设置来限制VisualFoxPro使用的内存数量。如果必要,请使用SYS(3050)函数。

3.“作为图标”插入对象

当我们将一个OLE对象插入到字段中时,将它作为一个图标,而不要作为整个的对象。这样可以减少所需的存储空间,因为如果Visual

FoxPro同对象一起保存了一个“代表”映象,会占用大量的存储空间。另外,如使用图标,绘制该对象的性能也会提高,因为只需重画图标。

4.尽量使用人工链接和图象控件

使用人工链接对象更快,因为自动链接需要的通知时间较长,而且人工链接不需要启动OLE

服务器来绘制对象。如果不需要经常更新一个对象,请使用人工链接。

如果在一个应用程序中使用单独的位图(如,公司徽标),则图象控件要比OLE绑定型控件快得多。

5.使用SYS(3050)

这个SYS函数允许我们优化用于数据缓冲的前台和后台的内存大小。前台内存是指当VisualFoxPro

是前台(活动)应用程序时可用的内存。后台内存是指当VisualFoxPro是后台应用程序时可用的内存。

我们可以实际操作这些值,观察VisualFoxPro为它的数据缓冲占用多少内存,以优化我们的应用程序。

参考文献:

①胡维华主编《VisualFoxPro程序设计教程》,浙江科学技术出版社,杭州,2000。

②陈华生主编《VisualFoxPro教程》,苏州大学出版社