我在表单上有许多按钮,为用户提供附加信息,每个按钮使用DCount查看是否有任何信息要显示,如果有,打开弹出窗口显示它。一切都运行良好,但现在只需一个特定的按钮,打开弹出窗口需要30秒到1分钟,这显然是不可接受的。无法理解为什么它原本工作得很好但现在变得如此缓慢。所有其他按钮仍然在一秒钟内打开它们的形式。 VBA是:
Private Sub btnNotes_Click()
'open the popup notes for the current record, if there are associated records
If DCount("ID","qlkpIDForNotes") = 0 Then
MsgBox "There are no notes for this patient", vbOKOnly, "No information"
Else
DoCmd.OpenForm "fsubNotes",,,"ID = " & Me.displayID
End If
End Sub
正在查询的表有大约40,000行,其中检查其他按钮的最大表大约有12,000行。尝试直接在表上执行DCount而不是通过查询,但没有任何区别。还尝试从原始表中取出一部分数据,将大约1100行复制到一个新表中并对其进行测试。它还需要12秒才能打开。 任何想法,任何人?
答案 0 :(得分:2)
使用DCount()
只是为了查明表或查询中是否有任何行可能效率很低,因为DCount()
必须运行整个查询并通过所有记录都返回总计数,以便您可以将其与0
进行比较。
根据查询的复杂性及其中的连接以及连接是否使用具有索引的字段,必须运行该查询的成本可以与基础表中的记录数成指数比例
要解决您的问题,请尝试以下方法:
确保ID
查询中基础表的qlkpIDForNotes
字段有索引,并且JOIN
或WHERE
子句中使用的所有字段都有也有索引。
检查您是否可以使用主要基础表或使用简化查询来测试qlkpIDForNotes
是否有可能返回的记录,简而言之,您可能不需要在只是为了找出它是否会有一些记录。
当您只需查看查询是否返回任何结果时,请使用单独的函数,例如HasAny()
而不是DCount()
:
'-------------------------------------------------------------------------'
' Returns whether the given query returned any result at all. '
' Returns true if at least one record was returned. '
' To call: '
' InUse = HasAny("SELECT TOP 1 ID FROM Product WHERE PartID=" & partID) '
'-------------------------------------------------------------------------'
Public Function HasAny(ByVal selectquery As String) As Boolean
Dim db As DAO.database
Dim rs As DAO.RecordSet
Set db = CurrentDb
Set rs = db.OpenRecordset(selectquery, dbOpenForwardOnly)
HasAny = (rs.RecordCount > 0)
rs.Close
Set rs = Nothing
Set db = Nothing
End Function
有了这个,您只需将代码重写为:
Private Sub btnNotes_Click()
'open the popup notes for the current record, if there are associated records '
If Not HasAny("qlkpIDForNotes") Then
MsgBox "There are no notes for this patient", vbOKOnly, "No information"
Else
DoCmd.OpenForm "fsubNotes",,,"ID = " & Me.displayID
End If
End Sub