网页功能: 加入收藏 设为首页 网站搜索  
优化程序速度
发表日期:2003-06-23作者:杜运庆[] 出处:  

速度是程序的命,如果您的软件再好,但运行速度很慢,那么您将失去用户耐心。VB6在操纵数据

库方面做的很出色,但操纵表的还是用SQL语句快,好在VB6的DAO对象、ADO对象和数据环境、ADO

控件都可以使用SQL语句,但怎么提高数据操纵速度呢?建立索引当然是最基本的要求,除此之外

呢?有没有其他的方法?第一VB论坛(http://www.d1vb.com)的网友经常提出这个问题,这里我

告诉您几种优化的方法:

一、表的设计

当在表中添加字段的时候,应该选择长度最小的数据类型,这样表在内存中每页可以存储更多的记

录。如:“姓名”字段一般设置为TEXT类型,长度为10一般就够用,则比默认的255要好的多。整

型Integer的长度是2,在使用整型Integer就可以解决问题的地方不要使用Single、Long、

Double、Currency,因为它们的长度分别为4、4、8、8,都比2大。在建立表后一定要建立

索引,这可以大大提高查询速度,是提高速度最基本的要求。

二、压缩数据库

JET数据库的查询优化是有代价的,随着数据库的不断扩大,优化将不再起作用。压缩数据库会改

变数据库的状态,并重新优化所有查询。同时,随着数据库的增大,会产生很多碎片。而压缩数据

库可以把一个表中的数据数据写到硬盘中连续的页里,提高了顺序搜索的速度。

压缩数据库使用CompactDatabase命令,下面的语句压缩数据库并产生一个数据库备份:

DBEngine.CompactDatabase “C:\VB\BIBLIO.MDB”, “C:\VB\BIBLIO2.MDB”

  Kill “C:\VB\BIBLIO.BAK”  Name “C:\VB\BIBLIO.MDB” As “C:\VB\BIBLIO.BAK”

  Name “C:\VB\BIBLIO2.MDB” As “C:\VB\BIBLIO.MDB”

注意,如果数据库很大的话,可能需要整夜的时间来压缩数据库。

三、避免查询输出里面多余的计算

当查询的结果作为另外一个查询的数据源的时候,可能引起查询优化问题。在这个时候第一次查询

里面尽量避免大量的计算。在如下示例中,Query1是第一个查询的结果,然后它作为第二个查询

的数据源。

Dim DB As Database

Dim RS As RecordSet

  Set DB = DBEngine.Workspaces(0).Opendatabase(“Biblio.MDB”)

  DB.CreateQueryDef(“Query1”, _

   “SELECT IIF(Au_ID=1,’Hello’,’Goodbye’) AS X FROM Authors”)

  Set RS = DB.OpenRecordSet(“SELECT * FROM Query1 WHERE X=’Hello’”)

由于在第一个查询Query1中的IIF()表达式不能被优化,,所以在第二个查询中的WHERE子句也不

能被优化。如果一个表达式在一个查询树中埋藏的很深的话,则这个查询不可被使用,它是不可优

化的。

如果可能的话,把这个SQL语句合并为一个没有嵌套的SQL语句:

Set RS = DB.OpenRecordSet(“SELECT * FROM Authors WHERE Au_ID=1”)

对于更灵活的嵌套查询,尽量在SQL语句中使用字段名,如:

DB.CreateQueryDef(“Query1”, _

   “SELECT IIF(Au_ID=1,’Hello’,’Goodbye’) AS X, Au_ID, FROM Authors”)

  Set RS = DB.OpenRecordSet(“SELECT * FROM Query1 WHERE Au_ID=1”)

如果在查询输出中实在无法避免计算式的话,尽量把计算式放在最外层,不要放在最内层。

四、只输出需要的字段

在建立查询的时候,仅返回需要的字段,这样可以节省不必要的开支。如果某个字段不是你需要

的,不要在查询语句中出现。上面的事例正说明了这个问题。

五、分组、合并及汇总

这里要说明的主要是合并,当你需要把两个表合并,就是说:当你要根据“Customer Name”对两

个表进行合并,要肯定GROUP BY field (Customer Name)和汇总(Sum, Count, and 等)的字段

是来自同一张表。

例如:下列语句优化性较差,因为SUM子句来自Ord表,而GROUP BY子句来自Cust表:

SELECT Cust.CustID,

     FIRST(Cust.CustName) AS CustName,

     SUM(Ord.Price) AS Total

  FROM Cust INNER JOIN Ord ON Cust.CustID = Ord.CustID

  GROUP BY Cust.CustID

如果按照Ord.CustID分组,查询性能就好的多了:

SELECT Ord.CustID,

     FIRST(Cust.CustName) AS CustName,

     SUM(Ord.Price) AS Total

  FROM Cust INNER JOIN Ord ON Cust.CustID = Ord.CustID

  GROUP BY Ord.CustID

六、尽量减少分组的字段

SQL语句中分组(GROUP BY)的字段越多,执行查询的时间越长。在GROUP BY子句中尽量用

aggregate函数来减少字段的数量。

如:

GROUP BY As Few Fields As Possible

  SELECT Cust.CustID,

     Cust.CustName,

     Cust.Phone,

     SUM(Ord.Price) AS Total

  FROM Cust INNER JOIN Ord ON Cust.CustID = Ord.CustID

  GROUP BY Cust.CustID, Cust.CustName, Cust.Phone

可以改为:: 

  SELECT Ord.CustID,

     FIRST(Cust.CustName) AS CustName,

     FIRST(Cust.Phone) AS Phone,

     SUM(Ord.Price) AS Total

  FROM Cust INNER JOIN Ord ON Cust.CustID = Ord.CustID

  GROUP BY Ord.CustID

七、在合并之前嵌套GROUP BY子句

如果要合并两张表,而且只在一张表中分组,把查询分为两个SELECT语句要快的多。

如: 

  SELECT Ord.CustID,

     FIRST(Cust.CustName) AS CustName,

     FIRST(Cust.Phone) AS Phone,

     SUM(Ord.Price) AS Total

  FROM Cust INNER JOIN Ord ON Cust.CustID = Ord.CustID

  GROUP BY Ord.CustID

可改为: 

查询1:

  SELECT CustID, SUM(Price) AS Total

  FROM Ord

  GROUP BY CustID

查询2:

  SELECT Query1.CustID, Cust.CustName, Cust.Phone, Query1.Total

  FROM Cust INNER JOIN Ord ON Cust.CustID = Ord.CustID

八、在合并的时候两边的字段都设置索引

在合并表的时候,尽量使两边的字段都设置索引。这在执行查询的时候查询优化器可以更多的使用

sophisticated 内部合并策略。

当然,在关系型数据库中,表要设计的尽量小,(最好1-2K页),这样删除表的索引的时候要快

的多,这是因为内存中读入了很少的页。这需要根据实际情况多次测试。

九、添加索引来提高查询和排序的速度

为合并或查询条件中的所有使用字段建立索引。Microsoft Jet 2.0极其以后版本的数据库引擎

使用使用了Rushmore查询优化技术,因此支持一张表的复合索引。

要尽量避免在查询条件中进行计算或在查询条件中使用未索引的字段。排序更是如此,绝对要避免

计算或使用未索引的字段。

十、使用可优化的表达式

重新构造查询语句,以便于Rushmore技术可以对其进行优化。Rushmore是一种数据访问技术,使

用它可以提高记录集的查询速度。使用Rushmore的时候,若在查询条件中使用具体类型的表达

式,查询速度将非常快。Rushmore不会自动为你的查询提高速度,你必须按照具体的方法修改查

询语句,以便于Rushmore可以优化它们。

十一、用COUNT(*)代替 COUNT([Column Name])

Microsoft Jet数据库引擎有特别的优化方法,它在使用COUNT(*)要比用COUNT([Column Name])

快得多。

注意,这两个运算符是有差别的:

Count(*) 计算所有的行。 

Count([Column Name])计算所有Column Name非空的行。

十二、在变量中避免使用LIKE

由于在查询完成的时候变量的值不确定,所以无法使用索引,这样,建立的索引就失去了意义,这

就严重制约着查询速度。

十三、避免LIKE和统配符同时使用

如果要把LIKE运算符同统配符一起使用,为了使用索引,必须把统配符放在后面。

如,下列语句利用了索引。

  Like "Smith"

  Like "Sm*"

而下列语句根本没有使用索引: 

  Like "*sen"

  Like "*sen*"

十四、测试合并约束

如果要在合并中使用表达式约束一个字段的数值,需要测试表达式放在合并的一侧,还是其他地

方,看哪种查询的速度较快。在一些查询中,表达式放在合并关键词join一侧反而比较快。

十五、使用中间结果表

用SELECT INTO建立工作表,尤其是结果集用于几个查询的时候,尽量使用中间结果表。在查询前

做的准备工作越多,查询速度越快。

十六、避免子SELECT语句和NOT IN同时使用

子SELECT语句和NOT IN同时使用很难优化,取反嵌套的查询或OUTER JOINs影响很大。

下列事例查询不在orders表中的用户:

优化前:

   SELECT Customers.*

   FROM Customers

   WHERE Customers.[Customer ID]

      NOT IN (SELECT [Customer ID] FROM Orders);

优化后: 

   SELECT Customers.*

   FROM Customers LEFT JOIN Orders

      ON Customers.[Customer ID] = Orders.[Customer ID]

   WHERE ((Orders.[Customer ID] Is Null));

我来说两句】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 优化程序速度
本类热点文章
  如何学好VB
  如何学好VB
  一个自杀程序
  一个自杀程序
  Visual Basic6.0实现自动化测试
  VB问题集锦及编程技巧
  VB问题集锦及编程技巧
  如何在VB中实现ActiveX控件的IobjectSa..
  VB计算农历的算法
  VB计算农历的算法
  RSA加密算法在VB中的实现
  在VB中调用CHM帮助的几种方法
最新分类信息我要发布 
最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放  
Copyright ©2003-2024 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00424