sql - 通过 "caching"表 Access 提高DLookup的速度还是其他策略?

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

背景

我有一个带有 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/

相关文章:

mysql - 在创建 UNIQUE 键之前如何定位重复记录?

mysql - 使用 slice 执行 sql 准备语句

php - sql - 在没有额外查询的情况下更新时检查行是否存在?

java - UCanAccess 似乎无法使用 getBytes() 读取 OLE 对象列

excel - VBA - 选择图表A的系列1时使图表B出现

c# - 用于超大型应用程序的 ASP.NET 自定义成员身份提供程序

django - django 的 MS Access 后端

ms-access - 空 Access-VBA 的使用无效

vba - 使用 VBA 发送消息时更改 Outlook 中的 "Item.To"值

VBA 运行循环,直到达到实例数