【问题标题】:Access increase speed of DLookup by "caching" tables or other strategy?通过“缓存”表或其他策略来提高 DLookup 的访问速度?
【发布时间】:2014-02-21 19:16:24
【问题描述】:

背景

我有一个带有 multiple DLookups 的 Access 拆分表单。表单上总共有大约 10 个 DLookup,Splitform 视图中的任何时候都会显示大约 25-50 条记录。

Access 前端链接到 SQL 表。

当 DLookup 值显示在数据表视图中时,查看信息会变得很慢,因为需要频繁重新计算(每次数据集中的任何内容发生更改时,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 秒。在公司 Intranet 上工作时,我的平均时间仍然超过 0.10 秒。两者在速度上非常相似。

这会导致表单刷新非常慢以及数据表刷新非常慢。

然后我针对托管在我机器上的 SQLExpress 数据库进行了测试 - 时间平均下降到 0.0005 秒。

问题

在这个应用程序中 DLookups 似乎很慢。我希望找到另一种更快的方法。

我希望喜欢能够以某种方式导致 DLookup 针对本地表运行 Access 大概保留而不是服务器上的 SQL 表。似乎我可以在每次打开表单或数据库(不是粉丝)时创建临时表 - 有更好的方法吗?

如果我指的是另一个 Access 数据库,我似乎可以使用“opendatabase”,然后将其保存在内存中。然后,这会提高对该数据库的查询速度。不过,我发现的 100% 示例都指的是 Access 数据库,而不是 SQL。

或者,我可以使用 DLookup 以外的其他东西,这是我在测试 SQL 命令时的想法,但我不确定该怎么做,因为 SQL 的速度相当。

【问题讨论】:

    标签: sql ms-access vba ms-access-2010


    【解决方案1】:

    如果它只是单个值,那么我倾向于使用简单的内存缓存 -

    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 后端时,我也发现这类事情很有用。

    【讨论】:

    • +1 我也在考虑类似的事情。对于@enderland,我认为这是一个“DLookup 数据的波动性如何?”的问题。对于相对静态的查找,像这样的东西可能会工作得很好。 (p.s. 你最近为 SO 做出了很多非常好的贡献。谢谢!)
    • 啊,这太明显了,我几乎无法处理它。我想说我以前从未使用过这些对象或做过类似的事情,但是,我不能。我打算在星期一试试这个(这实际上让我想在今天晚些时候呆在这里,因为我无法想象它不能很好地工作) - 我的 99.9% 的查找都是静态的,这会让我觉得很荒谬时间!
    • 这是加快许多此类查找的好方法。非常感谢!
    猜你喜欢
    • 2020-07-29
    • 2019-04-25
    • 1970-01-01
    • 2013-05-31
    • 1970-01-01
    • 2012-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多