然后在Access 2007中的DCount然后OpenForm查询太慢了

时间:2012-10-15 07:11:09

标签: ms-access-2007 access-vba

我在表单上有许多按钮,为用户提供附加信息,每个按钮使用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秒才能打开。 任何想法,任何人?

1 个答案:

答案 0 :(得分:2)

使用DCount()只是为了查明表或查询中是否有任何行可能效率很低,因为DCount()必须运行整个查询并通过所有记录都返回总计数,以便您可以将其与0进行比较。

根据查询的复杂性及其中的连接以及连接是否使用具有索引的字段,必须运行该查询的成本可以与基础表中的记录数成指数比例

要解决您的问题,请尝试以下方法:

  1. 确保ID查询中基础表的qlkpIDForNotes字段有索引,并且JOINWHERE子句中使用的所有字段都有也有索引。

  2. 检查您是否可以使用主要基础表或使用简化查询来测试qlkpIDForNotes是否有可能返回的记录,简而言之,您可能不需要在只是为了找出它是否会有一些记录。

  3. 当您只需查看查询是否返回任何结果时,请使用单独的函数,例如HasAny()而不是DCount()

  4. '-------------------------------------------------------------------------'
    ' 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