优化程序速度

原创 2007年10月08日 17:33:00

优化程序速度  
  速度是程序的命,如果您的软件再好,但运行速度很慢,那么您将失去用户耐心。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));   
 

每天三道冲刺工作--编写反转字符串的程序,要求优化速度、优化空间。

编写反转字符串的程序,要求优化速度、优化空间。 思路 : 例如 str ="abcd"   长度是4 ,只需要进行a 与d  b 与 c交换  声明两个指针,不开辟新的空间,指针p ,s ...
  • hahavslinb
  • hahavslinb
  • 2015-05-06 11:25:19
  • 346

VS2008 影响程序大小和速度的选项

下面要说的,都是默认值是release的,debug版本一般不需要调选项。 项目 - 属性 - 配置属性 - C/C++ 【优化】:  通常,算法程序选择最大化速度(/O2),界面程序选择最小化...
  • hellokandy
  • hellokandy
  • 2016-08-02 12:51:17
  • 1641

最基本的C语言代码级别速度优化

6年前写的东西,很不完善,但是也是过去的一个小小总结,主要针对x86平台,收藏如下:Short to int描叙:在32位的程序中,使用int类型作循环体的索引变量比short类型具有更好的性能。循环...
  • chinacodec
  • chinacodec
  • 2009-03-04 22:11:00
  • 2967

VC++代码执行速度优化

本文主要整理MSDN几篇关于VC++编译器优化的几篇文章,试验并总结了一个简单易用的VC++代码优化的攻略。 一、基础知识     VC++代码优化分为两类:代码大小优化和代码速度优化。本文主要关...
  • Sagittarius_Warrior
  • Sagittarius_Warrior
  • 2017-02-24 09:58:37
  • 1011

初级前端小程序项目加载速度优化

这份文字是根据近期团队做来问丁香医生 SPA 和 丁香医生小程序 加载速度优化的经历整理而成。 效果 古人有一句话叫做:治感冒看疗效。既然是关于速度优化的,我们就先来看一下优化的效果。 ...
  • rolan1993
  • rolan1993
  • 2018-01-04 11:18:48
  • 595

提高程序运行速度的方法

1、选择一组合适的算法和数据结构; 2、编写出编译器能够有效优化的源代码;(编写程序方式中一点小小的变动,都会引起编译器优化方式的很大变化,必须了解编译器的能力和局限性,有些编程语言比其他语言容易优...
  • BTNZF
  • BTNZF
  • 2015-04-27 11:07:35
  • 907

sse优化一例

sse优化一例
  • jacke121
  • jacke121
  • 2017-01-24 10:29:38
  • 267

编写反转字符串的程序,要求优化速度、优化空间

这是网络流传的Microsoft的面试题目之一:“编写反转字符串的程序,要求优化速度、优化空间”。 因为最近一直很多关注算法方面的实践和研究,因此对这个问题进行了一些思考,给出了5种实现方法(有两种...
  • sunstars2009918
  • sunstars2009918
  • 2011-09-11 16:04:20
  • 3232

VS优化Release代码速度

右键工程->配置属性->C/C++->优化-> “优化”:使速度最大化; “优选大小或速度”:代码速度优先 原来每帧170ms提高到了70ms........
  • zinnc
  • zinnc
  • 2016-09-09 22:28:37
  • 1811

Android 性能优化 冷启动速度优化

前言本篇文章对app启动速度进行优化。先了解 Android 性能优化 基本概念应用是如何启动的,会对此有帮助。1. 应用的启动模式 冷启动 Cold start 当启动应用时,后台没有该应用的进程...
  • u014099894
  • u014099894
  • 2016-11-30 17:48:07
  • 2107
收藏助手
不良信息举报
您举报文章:优化程序速度
举报原因:
原因补充:

(最多只允许输入30个字)