从.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回答。
| |
|
|
| |
|
|