背景
我有一个带有 multiple DLookups 的 Access splitform。表单上总共有大约 10 个 DLookup,并且在 Splitform View 中的任一时间显示大约 25-50 条记录。
Access 前端链接到 SQL 表。
当 DLookup 值显示在数据表 View 中时,查看信息会变得很慢,因为频繁重新计算(每次数据集中的任何内容更改时,Access 似乎都会重新计算整个 Splitform 数据表的所有 DLookup)。通过 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/

10-09 00:46