Excel 如何加快批量';向上插入';在Microsoft Access中
我正在使用VBA字典在Access中执行“upsert”。我正在循环我的字典键,如果该键存在于访问表中,那么我会更新它。如果没有,则将其插入。然而,我的表包含200k+行,这使得代码执行速度非常慢(例如,5分钟,甚至还没有完成5%),因为迭代需要在整个表中搜索“LOC”(我的键) 我有没有办法显著加快这一进程? 我的代码如下,任何帮助都将不胜感激Excel 如何加快批量';向上插入';在Microsoft Access中,excel,vba,ms-access,dao,Excel,Vba,Ms Access,Dao,我正在使用VBA字典在Access中执行“upsert”。我正在循环我的字典键,如果该键存在于访问表中,那么我会更新它。如果没有,则将其插入。然而,我的表包含200k+行,这使得代码执行速度非常慢(例如,5分钟,甚至还没有完成5%),因为迭代需要在整个表中搜索“LOC”(我的键) 我有没有办法显著加快这一进程? 我的代码如下,任何帮助都将不胜感激 Sub UpdateDatabase(dict As Object) Dim db As Database Dim rs As DAO.Record
Sub UpdateDatabase(dict As Object)
Dim db As Database
Dim rs As DAO.Recordset
Set db = OpenDatabase("C:\XXX\myDB.accdb")
Set rs = db.OpenRecordset("MyTable", dbOpenDynaset)
For Each varKey In dict.Keys()
'Table is searched for key
rs.FindFirst "[LOCID] = '" & varKey & "'"
If rs.NoMatch Then
'If the key was not found, insert it
rs.AddNew
rs!LOCID = varKey
rs![Status] = "To Start"
rs.Update
Else
'If the key was found, update its status
rs.Edit
rs![Status] = "Done"
rs.Update
End If
Next
rs.Close
db.Close
Application.StatusBar = False
End Sub
编辑:
我在上面的代码中找到了瓶颈。这是一条线:
rs.FindFirst "[LOCID] = '" & varKey & "'"
这用于查找密钥是否在数据库中。删除此项(以及简单地插入新数据)可以加快处理速度,并且只需几秒钟即可完成。有没有一种快速方法可以确定表中是否已经存在值?首先:
dict集合有多大。(5、10或1000??)
接下来,LOCID是该表“MyTable”中的索引列
如果LOCID已经是索引列,则可以使用以下代码。它应该能将速度提高100倍或更多倍:
假设该表不是链接表,而是数据库中的一个表
请注意,您必须以“actable”的形式打开有问题的表——这是默认设置,因此我删除了dbOpenDynaset)
此代码将实现以下功能:
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = OpenDatabase("C:\XXX\myDB.accdb")
Set rs = db.OpenRecordset("MyTable") ' <--- note this!!!
rs.Index = "LOCID"
For Each varKey In dict.Keys()
'Table is searched for key
rs.Seek "=", varKey
If rs.NoMatch = True Then
'If the key was not found, insert it
rs.AddNew
rs!LOCID = varKey
rs![Status] = "To Start"
rs.Update
Else
'If the key was found, update its status
rs.Edit
rs![Status] = "Done"
rs.Update
End If
Next
rs.Close
db.Close
Dim db作为DAO.Database
Dim rs作为DAO.Recordset
Set db=OpenDatabase(“C:\XXX\myDB.accdb”)
Set rs=db.OpenRecordset(“MyTable”)”首先:
dict集合有多大。(5、10或1000??)
接下来,LOCID是该表“MyTable”中的索引列
如果LOCID已经是索引列,则可以使用以下代码。它应该能将速度提高100倍或更多倍:
假设该表不是链接表,而是数据库中的一个表
请注意,您必须以“actable”的形式打开有问题的表——这是默认设置,因此我删除了dbOpenDynaset)
此代码将实现以下功能:
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = OpenDatabase("C:\XXX\myDB.accdb")
Set rs = db.OpenRecordset("MyTable") ' <--- note this!!!
rs.Index = "LOCID"
For Each varKey In dict.Keys()
'Table is searched for key
rs.Seek "=", varKey
If rs.NoMatch = True Then
'If the key was not found, insert it
rs.AddNew
rs!LOCID = varKey
rs![Status] = "To Start"
rs.Update
Else
'If the key was found, update its status
rs.Edit
rs![Status] = "Done"
rs.Update
End If
Next
rs.Close
db.Close
Dim db作为DAO.Database
Dim rs作为DAO.Recordset
Set db=OpenDatabase(“C:\XXX\myDB.accdb”)
Set rs=db.OpenRecordset(“MyTable”)”与其他人的建议相同;从根本上说,不要做循环。执行操作查询(追加或更新)
这是“程序员”和“数据库开发人员”之间最常见的区别……其他人的建议也是如此;从根本上说,不要做循环。执行操作查询(追加或更新)
这是“程序员”和“数据库开发人员”之间最常见的区别。…您可以定期调用UpdateBatch,而不是在每次更改之后。。。您的字典中有多少条目?@TimWilliams我发现性能瓶颈实际上不是添加数据,而是在确定值是否已在表中的代码中。我已经编辑了我的问题。可能是重复的。请参阅描述连接表的查询的答案。@June7我相信我所针对的方法的差异足以保证提出一个新问题。我的目标是使用DAO提高性能。DAO循环的工作速度比查询慢得多。如果需要性能,请使用查询,否则,如果是教程示例或性能实验,请确保键列具有索引,并使用Seek
方法而不是FindFirst
您可以定期调用UpdateBatch,而不是在每次更改之后。。。您的字典中有多少条目?@TimWilliams我发现性能瓶颈实际上不是添加数据,而是在确定值是否已在表中的代码中。我已经编辑了我的问题。可能是重复的。请参阅描述连接表的查询的答案。@June7我相信我所针对的方法的差异足以保证提出一个新问题。我的目标是使用DAO提高性能。DAO循环的工作速度比查询慢得多。如果需要性能,请使用查询,否则,如果是教程示例或性能实验,请确保键列具有索引,并使用Seek
方法,而不是FindFirst
,我想我们都同意这一点。但是,包含键列表的对象正在传递给例程。不清楚该列表的来源,但所提供的数据不是表格格式,也不是我们知道的数据源。毫无疑问,如果该数据来自某个表源,则首选操作查询。var“dict”是一个对象,它甚至不知道该数据是否来自给定发布代码中的表。如果有办法获取一个对象集合,并将其转换为一个查询,那么我洗耳恭听。我想我们都同意。但是,包含键列表的对象正在传递给例程。不清楚该列表的来源,但所提供的数据不是表格格式,也不是我们知道的数据源。毫无疑问,如果该数据来自某个表源,则首选操作查询。var“dict”是一个对象,它甚至不知道该数据是否来自给定发布代码中的表。如果有一种方法可以获取一个对象集合,并将其转换为一个查询,那么我洗耳恭听。