热情软件屋

 

从.dbf到.mdb查找更新速度慢


编号:QA004209
建立日期: 2001年5月21日 最后修改日期:2001年6月4日
所属类别:

风满楼:
    操作系统:Windows98
    编程工具:Visual Basic 6.0
    问题:从.dbf到.mdb查找更新速度慢。我在用vb6.0对数据库进行搬迁,从.dbf数据到.mdb数据。情况如下:
    现有两个.dbf数据库old1.dbf,old2.dbf,其中old1.dbf中有7000余数据,old2.dbf中有8000条数据,old1.dbf与old2.dbf有一个共同字段stu_ID,其它字段相互补充,且old2.dbf比old1.dbf多一些stu_ID。
    现在我已经把old1.dbf中的数据加入到new.mdb中的一个表中,采取逐条记录加入方式,用了二三十余秒,速度还算可以。但加入old2.dbf中的数据时,我采用data数据控件对old2.dbf操作,用ado源码对new.mdb操作(不是ado控件),对old2.dbf中的每一条记录的stu_ID字段都在new.mdb中查找,如没找到则addnew,update,如找到则直接update。使用这种方法,加入old2.dbf用了六七分钟,时间过长,不知问题出在什么地方,请指正,谢谢!源程序如下:
    For i = 1 To recCount '到old2.dbf中的最大记录数
     '下面条件语句是限定字段不能空的情况
     If datdbf.Recordset.Fields(stu_IDPos) <> vbNullString Then
     tempstuID = datdbf.Recordset.Fields(stu_IDPos)
     '下面的rs是指向new.mdb的Recordset对象
     rs.Open "SELECT * FROM tblNew WHERE stu_ID='" & Trim(tempstuID) & "'"
     '如果rs返回为空,即是新的stu_ID号,那么加一个新记录,其中Name字段是old1.dbf中没有的
     If rs.BOF Or rs.EOF Then
     rs.AddNew
     rs.Fields("stu_ID") = Trim(tempstuID)
     If datdbf.Recordset.Fields(NamePos) <> vbNullString Then
     tempName = datdbf.Recordset.Fields(NamePos)
     rs.Fields("Name") = Trim(tempName)
     Else
     rs.Fields("Name") = Trim("")
     End If
     rsGSDM.Update
     '如果rs返回不为空,那么更新处理
     Else
     If datdbf.Recordset.Fields(NamePos) <> vbNullString Then
     tempName = datdbf.Recordset.Fields(NamePos)
     rs.Fields("Name") = Trim(tempName)
     Else
     rs.Fields("Name") = Trim("")
     End If
     rs.Update
     End If
     rs.Close '再次使用rs.open前的关闭
     End If
     datdbf.Recordset.MoveNext 'dbf库指针下移
    Next i
    水平: 中级

回答:

    对于这个问题,我想应该是因为你在第一次向new.mdb中添加old1.dbf时,是逐条添加,7000多条记录用二十多秒是比较正常的,但是在你用old2.dbf更新new.mdb时,因为你每更新一条记录都要使用select语句查找stu_ID号,这相当于你每更新一条记录,就又对new.mdb库查找了一遍,根据查找的平均时间,也是遍历全记录的一半左右,8000多条记录,就是你又对new.mdb遍历了8000多遍,所以你第二次用时六七分钟也是有可能的。
    如果你想提高速度,你可以先对old2.dbf和new.mdb以stu_ID进行相同升序或降序排序,然后从头开始,利用比较插入法:如下
     if old2.stu_ID>new.stu_ID then '如果old2.stu_ID大,不用插入,new记录后移
     new.skip
     else if old2.stu_ID     new.addnew(old2.stu_ID)
     old2.skip
     else if old2.stu_ID=new.stu_ID then '如果相等,更新new记录,两表记录都后移
     new.update(old2.stu_ID)
     new.skip
     old2.skip
     end if
     end if
     end if
    利用这个方法可以所用的平均时间就是对old2和new遍历一遍,一共用两遍就可以完成估计大概用时在50秒以内。但是排序可能要花去一定的时间,你可以比较一下,看这种方法是否可以节省时间。
    
    caozhen的意见:
    我想问题在于你在循环体内打开Recordset的缘故。即:
     rs.Open "SELECT * FROM tblNew WHERE stu_ID='" & Trim(tempstuID) & "'"
    使用ado打开数据比较慢(比DAO慢),特别RS的游标类型是客户端游标时。
    事实上你可以在循环体外打开rs,如下:
     rs.Open "Select * from tblNew"
    然后在循环体内使用Find方法查找是否有满足条件的记录:
     rs.MoveFirst '在ADO中,这句不可少
     rs.Find "stu_ID ='" & tempstuID & "'"
     If rs.EOF Then
     '添加记录
     Else
     '更新记录
     End If

此问题由zhangpk回答。

 
把这个问题推荐给朋友
   
   
您的意见类别
您的名字
您的电子邮件
您的建议(请尽可能详细)
 
 

版权所有 1997-2008 热情软件屋
如果您有任何建议和意见, 请给我发个电子邮件 askpro@china-askpro.com
Web Designed by ZebraStudio