Ms access &引用;Select语句中的最小值;或DMin()。哪一个更好?
我需要从表tbl_revenue中找到最低收入。我找到了两种方法: 方法1Ms 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)=
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'))")
我有以下问题:
在您的特定代码中,您只运行了一次,因此不会产生太大的差异。如果它在一个循环或一个查询中,并且您正在组合数百或数千次迭代,那么您将遇到问题 如果数千次迭代的性能对您来说很重要,我将编写如下内容:
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在你的答案上——你链接到的线程非常吸引人,并且有一些很棒的建议。学到了很多-谢谢!