背景
我有一个带有 multiple DLookups 的 Access splitform 。表单上总共大约有 10 个 DLookups,Splitform View 中任一时间大约显示 25-50 条记录。
Access 前端链接到 SQL 表。
当 DLookup 值显示在数据 TableView 中时,查看信息会变得非常慢,因为需要频繁重新计算(每次数据集中的任何内容发生更改时,Access 都会重新计算整个 Splitform 数据表的所有 DLookups)。通过 VPN 连接时,速度非常明显且难以接受。
研究
我决定进行调查并编写以下内容来确定为什么事情如此缓慢。我还想检查 DLookup 是否由于某种原因比 SQL 查询慢。
sub testLotsofDlookups()
Dim count As Integer
Dim startTime As Date
Dim endTime As Date
Dim numbTries As Integer
Dim t As String
numbTries = 100
startTime = Now
count = 0
Dim dbs As DAO.database
Dim rsSQL As DAO.Recordset
Dim strSQL As String
Set dbs = CurrentDb
'Open a snapshot-type Recordset based on an SQL statement
strSQL = "Select FullName from ToolDesigners Where ToolDesignersID=4;"
startTime = Now
For count = 1 To numbTries
Set rsSQL = dbs.OpenRecordset(strSQL, dbOpenSnapshot)
t = rsSQL.Fields(0)
Next count
Dim mDiff As Double
mDiff = DateDiff("s", startTime, Now)
Debug.Print "SQL Total time:" & vbTab & DateDiff("s", startTime, Now)
Debug.Print "SQL Average time:" & vbTab & mDiff / numbTries
'
'
'
'
'
startTime = Now
For count = 1 To numbTries
t = DLookup("FullName", "ToolDesigners", "ToolDesignersID=4")
Next count
mDiff = DateDiff("s", startTime, Now)
Debug.Print "DLookupUp Total time:" & vbTab & DateDiff("s", startTime, Now)
Debug.Print "DLookupUp Average time:" & vbTab & mDiff / numbTries
end sub
(我知道这仅精确到单秒)
有趣的是,我发现平均每个 DLookup 和 SQL 查询花费了近 0.5 秒。在公司内网工作时,我平均还有0.10秒以上的时间。两者在速度上非常相似。
这会导致表单刷新非常慢以及数据表刷新非常慢。
然后,我针对我的计算机上托管的 SQLExpress 数据库进行了测试 - 平均时间下降到 0.0005 秒。
问题
看起来 DLookups 在这个应用程序中很慢。我希望找到一种替代且更快的方法。
我希望能够做的是以某种方式使DLookup针对Access可能保留的本地表而不是服务器上的SQL表运行。看来我可以在每次打开表单或数据库时创建临时表(不是粉丝) - 有更好的方法吗?
如果我指的是另一个 Access 数据库,我似乎可以使用“opendatabase”,然后将其保留在内存中。这样就可以提高对该数据库的查询速度。我发现的 100% 示例都涉及 Access 数据库,而不是 SQL。
或者,我可以使用 DLookup 以外的其他工具,这是我在测试 SQL 命令时的想法,但我不太确定该怎么做,因为 SQL 的速度相当。
最佳答案
如果它只是单个值,那么我倾向于使用简单的内存缓存 -
Private mToolDesignerFullNameCache As New Scripting.Dictionary
Function GetToolDesignerFullName(Criteria As String)
If mToolDesignerFullNameCache.Exists(Criteria) Then
GetToolDesignerFullName = mToolDesignerFullNameCache(Criteria)
Else
Dim Name
Name = DLookup("FullName", "ToolDesigners", Criteria)
mToolDesignerFullNameCache.Add(Criteria, Name)
GetToolDesignerFullName = Name
End If
End Function
Sub ResetToolDesignerFullNameCache()
mToolDesignerFullNameCache.RemoveAll
End Sub
需要添加“Microsoft Scripting Runtime”作为 VBA 引用进行编译。过去,考虑到 Access UI 轮询数据的频率,即使使用 Access 后端,我也发现这种事情很有用。
关于sql - 通过 "caching"表 Access 提高DLookup的速度还是其他策略?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21943291/