我知道所有域聚合函数都很慢,但我正在寻找最少的邪恶。
以下两个选项中哪个更快?
GROUP BY
列相同的条件进行复制吗? 编辑1
我的问题是我在许多情况下都想知道的一般性问题,但下面是目前正在考虑的具体情况。
在我的时间输入详细信息子表单中,我需要显示在此作业中使用了多少材料。文本框的控件源如下所示:
=DLookUp("[SumOfPrice]","tm_materialsUsedByPart","[Part]=" & [cmbPart])
tm_materialsUsedByPart
目前是一个查询,总结了所有使用的材料。
使用具有完全相同标准的dsum或执行查询更快,然后获取符合我标准的单行会更快吗?
答案 0 :(得分:1)
还有两个选项:相关子查询或派生表。相关子查询需要将查询中的列声明为自己的查询:
Select ...
, ( Select Sum(Foo)
From Bar
Where Bar.FK = Gamma.PK ) As Total
From Gamma
Access中的派生表将涉及创建一个保存的查询,该查询执行所有总计,然后将该查询加入主查询。虽然可以在主查询中动态构建总计查询,但我的经验是Access对保存的查询和标准连接更满意。如果您向我们展示了您要完成的任务,您可能会得到一些更具体的答案。
修改强>
IMO,最快的解决方案是通过保存的查询将总数包含在表单的来源中。即,不使用DLookup或DSum,而是通过连接到计算总计的查询来将总数作为表单的RecordSource的一部分包括在内。
其次,要真正了解哪个函数的性能最佳,您需要对数据进行一些性能测试。我的猜测是两者之间的表现相当。即使对存储的查询使用DLookup,Access也应该足够聪明以注入过滤条件,并且实际上可以获得与使用DSum相当的执行计划。
最后,如果您要使用域聚合函数,并且DLookup中使用的查询的唯一目的是为此表单提供总计,那么IMO,使用DSum更有意义,因为它使您的意图域聚合函数的使用对读者来说更清晰。
答案 1 :(得分:1)
=DLookUp("[SumOfPrice]","tm_materialsUsedByPart","[Part]=" & [cmbPart])
如果没有看到tm_materialsUsedByPart的SQL,我们只能猜测它正在做什么。也许它读取整个表或一组JOINed表,并使用GROUP BY将Sum(Price)聚合为SumOfPrice。
对于基础表,DSum应该更快,特别是如果[Part]字段被编入索引。
=DSum("[Price]", "tblRowSource", "[Part]=" & Me.cmbPart)
这样你就要求数据库引擎只读取包含你想要的[Part]值的行。您的materialsUsedByPart查询需要读取所有行,然后提取所需的单个组值。不要那样做。要求数据库引擎读取尽可能少的行,以便为您提供所需的信息。
编辑:我错误地认为针对基表的DSum比针对聚合查询的DLookup更快。正如@Thomas建议的那样,在我的简单测试中,两种情况的查询计划是相同的。
这是我的查询 qryMinutesPerClient :
SELECT Time_Sub.CLIENT_ID, Sum(Time_Sub.MINUTES) AS SumOfMINUTES
FROM Time_Sub
GROUP BY Time_Sub.CLIENT_ID;
然后
DLookup("SumOfMINUTES","qryMinutesPerClient","CLIENT_ID = 11111")
会产生此查询计划:
- Inputs to Query -
Table 'Time_Sub'
- End inputs to Query -
01) Restrict rows of table Time_Sub
using rushmore
for expression "Time_Sub.CLIENT_ID=11111"
02) Group result of '01)'
并且
DSum("MINUTES","Time_Sub","CLIENT_ID = 11111")
计划是一样的:
- Inputs to Query -
Table 'Time_Sub'
- End inputs to Query -
01) Restrict rows of table Time_Sub
using rushmore
for expression "CLIENT_ID=11111"
02) Group result of '01)'
最重要的性能问题涉及“使用rushmore”,这是可能的,因为我的CLIENT_ID字段已编制索引。如果没有该索引,Rushmore就无法在查询计划中使用,并且DLookup和DSum方法都比Rushmore慢明显。