Ms access &引用;Select语句中的最小值;或DMin()。哪一个更好?

Ms access &引用;Select语句中的最小值;或DMin()。哪一个更好?,ms-access,vba,Ms Access,Vba,我需要从表tbl_revenue中找到最低收入。我找到了两种方法: 方法1 Dim MinRevenueSQL As String Dim rsMinRev As DAO.Recordset MinRevenueSQL = "SELECT Min(tbl_Revenue.Revenue_Value)As MinRevenue FROM tbl_Revenue WHERE (((tbl_Revenue.Division_ID)=20) AND ((tbl_Revenue.Period_Type)=

我需要从表tbl_revenue中找到最低收入。我找到了两种方法:

方法1

Dim MinRevenueSQL As String
Dim rsMinRev As DAO.Recordset
MinRevenueSQL = "SELECT Min(tbl_Revenue.Revenue_Value)As MinRevenue FROM tbl_Revenue WHERE (((tbl_Revenue.Division_ID)=20) AND ((tbl_Revenue.Period_Type)='Annual'));"
Set rsMinRev = CurrentDb.OpenRecordset(MinRevenueSQL)
MinRev = rsMinRev!MinRevenue
方法2

MinRev2 = DMin("Revenue_Value", "tbl_Revenue", "(((tbl_Revenue.Division_ID)=20) AND ((tbl_Revenue.Period_Type)='Annual'))")
我有以下问题:

  • 其中哪一个计算效率更高?如果不是tbl_收入表,而是使用联接的select语句,那么计算效率会有很大差异吗
  • DMin基金的准确性有问题吗?(我所说的准确性是指在使用DMin之前,我是否需要注意任何漏洞。)

  • 在您的特定代码中,您只运行了一次,因此不会产生太大的差异。如果它在一个循环或一个查询中,并且您正在组合数百或数千次迭代,那么您将遇到问题

    如果数千次迭代的性能对您来说很重要,我将编写如下内容:

    Sub runDMin()
        x = Timer
    
        For i = 1 To 10000
            MinRev2 = DMin("Revenue_Value", "tbl_Revenue", "(((tbl_Revenue.Division_ID)=20) AND ((tbl_Revenue.Period_Type)='Annual'))")
        Next
    
        Debug.Print "Total runtime seconds:" & Timer - x
    End Sub
    
    然后对DAO查询实现相同的功能,替换MinRev2部分。将它们都运行几次,取平均值。尽最大努力模拟将要运行的条件;例如,如果要更改每个查询中的参数,请执行相同的操作,因为这很可能会影响两个方法的性能。我在Access中使用DAO和ADO做了一些类似的事情,并惊讶地发现,在我的情况下,DAO运行得更快(这是几年前的事了,所以从那以后情况可能发生了变化)

    当在查询中使用DMin从外部表中获取最小值时,这肯定是有区别的。从Access文档:

    提示:尽管您可以使用DMin函数来查找最小值 从外部表中的字段创建 包含两个表中所需字段的查询,以及 以该查询为基础创建表单或报表

    但是,这与您的情况略有不同,您使用VBA方法运行这两种方法

    我倾向于相信(可能是错误的,因为我没有任何证据)域函数(DMin、DMax等)比使用SQL慢。如果您运行上面的代码,也许可以让我们知道结果如何

    如果您正确地编写了DMin调用,我就不知道有任何准确性问题。你听说了吗?本质上,调用应该是:
    DMin(“,”,“)


    祝你好运

    我怀疑答案可能因您的情况而异。
    在单用户情况下,@transistor1测试方法将为您提供一个独立查找的好答案

    但是在网络上共享的数据库上,如果您已经
    设置了db=CurrentDb
    ,那么
    选择方法应该更快,因为它不需要打开到数据库的第二个连接,这很慢

    同样,设置db=CurrentDb
    并在任何地方重用该db更有效。
    在我想确保自己拥有最佳速度的情况下,我会在打开应用程序时使用
    Public db作为DAO.Database
    。然后在每个需要的模块中,我使用

    如果db什么都不是,那么就设置db=CurrentDb

    只是好奇-为什么不管是使用set db=CurrentDb还是在任何地方都使用CurrentDb对象都很重要(除非您需要灵活性将其更改为CodeDB或其他东西)?OP正在使用CurrentDB。另外,您如何知道DMin正在打开一个单独的连接,而不是在内部使用CurrentDB对象?在某些情况下,我体验到使用CurrentDB不能正常工作,特别是当您多次提到它时——但坦率地说,我记不清细节。我认为这里有一个例子:+1非常有趣,谢谢你的链接。我一直想知道为什么这个问题不起作用,只是使用OpenRecordset()避开了它。我必须承认我倾向于将CurrentDb()看作一个对象,尽管我知道它是一个方法(通过IntelliSense)。我总是错误地假设CurrentDb()每次都返回相同的引用。FWIW-为了确认,我在即时窗口中调用了两次
    ?objptr(CurrentDb())
    ,得到了两个不同的响应:
    2305410
    2306366
    。在那之后,每个后续的电话都给了我
    2306366
    。更改某些代码并重新编译和保存数据库会产生一个新值:
    2303254
    。我想知道微软为什么会这样实施它——引用发生变化肯定有一个合理的原因。+1在你的答案上——你链接到的线程非常吸引人,并且有一些很棒的建议。学到了很多-谢谢!