简体   繁体   English

MS Access在查询或dsum上执行dlookup?

[英]MS Access performace dlookup on query or dsum?

I know that all of the domain aggregate functions are slow, but I am looking for the least of the evils. 我知道所有域聚合函数都很慢,但是我正在寻找最少的弊端。

Which will be the faster of the following two options? 以下两个选项中哪个更快?

  1. Create a query that will group by the unique value and sum the total. 创建一个查询,该查询将按唯一值分组并求和。 Have dlookup to get my sum from the query. 有dlookup从查询中获取我的总和。
  2. Do a dsum on the main table with the criteria being the same as my GROUP BY columns in option 1? 主表上的dsum是否与选项1中的GROUP BY列相同?

Edit 1 编辑1
My question is a generic question that I have wondered in many situations but below is a specific situation under consideration right now. 我的问题是一个我在许多情况下都想知道的通用问题,但以下是目前正在考虑的特定情况。

On my time entry detail subform I need to show how much materials have been used on this job. 在我的时间输入详细信息子表单上,我需要显示此工作使用了多少材料。 The control source for the textbox looks like this: 文本框的控件源如下所示:

=DLookUp("[SumOfPrice]","tm_materialsUsedByPart","[Part]=" & [cmbPart])

tm_materialsUsedByPart is currently a query that is summing up all the materials used. tm_materialsUsedByPart当前是一个查询,用于汇总所有使用的材料。

Would it be faster to use a dsum that have esentially the same criteria or is it faster to execute the query then grab the single row that matches my criteria? 使用基本具有相同条件的dsum会更快还是执行查询然后获取与我的条件匹配的单行会更快?

There are two other options: correlated subquery or derived table. 还有两个其他选项:相关子查询或派生表。 A correlated subquery would entail declaring a column in your query to itself be a query: 一个相关的子查询将需要在您的查询中声明一列本身就是一个查询:

Select ...
 , ( Select Sum(Foo)
     From Bar
     Where Bar.FK = Gamma.PK ) As Total
From Gamma

A derived table, in Access, would involve creating a saved query that does all the totals and then joining that query into your main query. 在Access中,派生表将涉及创建一个保存了所有总数的查询,然后将该查询加入到您的主查询中。 Although it is possible to build the totals query on the fly in the main query, my experience is that Access is happier with a saved query and a standard join. 尽管可以在主查询中动态构建总计查询,但我的经验是,使用保存的查询和标准联接,Access会更快乐。 If you show us more about what you are trying to accomplish, you might get some more specific answers. 如果您向我们展示更多您要完成的工作,则可能会得到一些更具体的答案。

EDIT 编辑

IMO, the fastest solution would be to include the total, via a saved query, in the source for the form. IMO,最快的解决方案是通过保存的查询将总计包括在表格的来源中。 Ie, not use either DLookup or DSum but instead include the total as part of the form's RecordSource by joining to a query that calculates the total. 即,不使用DLookup或DSum,而是通过加入计算总数的查询,将总数作为表单的RecordSource的一部分包含在内。

Second, to actually know which function will perform best, you would need to do some performance tests against your data. 其次,要真正知道哪个功能将发挥最佳性能,您需要对数据进行一些性能测试。 My guess is that the performance will be comparable between the two. 我的猜测是两者之间的性能可比。 Even with DLookup against a stored query, Access should be smart enough to inject the filtering criteria and in effect get a comparable execution plan to using DSum. 即使使用针对存储的查询的DLookup,Access也应足够聪明以注入筛选条件,并实际上获得与使用DSum相当的执行计划。

Lastly, if you are going to use a domain aggregate function and the only purpose of the query used in DLookup is to serve totals for this form, then IMO, it makes more sense to use DSum since it makes your intent for the use of the domain aggregate function clearer to the reader. 最后,如果您要使用域汇总函数,并且DLookup中使用的查询的唯一目的是为该表格(即IMO)提供总计,则使用DSum更有意义,因为它使您有意使用域聚合功能对读者来说更加清晰。

=DLookUp("[SumOfPrice]","tm_materialsUsedByPart","[Part]=" & [cmbPart])

Without seeing the SQL for tm_materialsUsedByPart, we can only guess at what it's doing. 在没有看到tm_materialsUsedByPart的SQL的情况下,我们只能猜测它在做什么。 Maybe it reads an entire table, or set of JOINed tables, and uses a GROUP BY to aggregate Sum(Price) as SumOfPrice. 也许它读取整个表或一组JOINed表,并使用GROUP BY将Sum(Price)汇总为SumOfPrice。

It should be faster to DSum against the underlying table, particularly if the [Part] field is indexed. DSum针对基础表的速度应该更快,尤其是在为[Part]字段建立索引的情况下。

=DSum("[Price]", "tblRowSource", "[Part]=" & Me.cmbPart)

That way you ask the database engine to only read the rows which contain the [Part] value you want. 这样,您要求数据库引擎仅读取包含所需[Part]值的行。 Your materialsUsedByPart query requires reading all the rows, then you extract the single group value you want. 您的materialsUsedByPart查询需要读取所有行,然后提取所需的单个组值。 Don't do that. 不要那样做。 Ask the database engine to read the fewest rows possible to get you the information you need. 要求数据库引擎读取最少的行,以获取所需的信息。

Edit : I was wrong that DSum against the base table would be faster than DLookup against an aggregate query. 编辑 :我错了,针对基表的DSum会比针对聚合查询的DLookup更快。 As @Thomas suggested, the query plan is the same for both cases in my simple test. 正如@Thomas建议的那样,在我的简单测试中,两种情况的查询计划都是相同的。

Here is my query, qryMinutesPerClient : 这是我的查询qryMinutesPerClient

SELECT Time_Sub.CLIENT_ID, Sum(Time_Sub.MINUTES) AS SumOfMINUTES
FROM Time_Sub
GROUP BY Time_Sub.CLIENT_ID;

Then 然后

DLookup("SumOfMINUTES","qryMinutesPerClient","CLIENT_ID = 11111")

results in this query plan: 结果在此查询计划中:

- 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)'

And with

DSum("MINUTES","Time_Sub","CLIENT_ID = 11111")

the plan is the same: 计划是一样的:

- 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)'

The most important performance issue involves "using rushmore", which is possible because my CLIENT_ID field is indexed. 性能上最重要的问题涉及“使用rushmore”,这是可能的,因为我的CLIENT_ID字段已建立索引。 Without that index, Rushmore can't be used in the query plan, and both DLookup and DSum approaches are noticeably slower than with Rushmore. 没有该索引,Rushmore不能在查询计划中使用,并且DLookup和DSum方法都明显比Rushmore慢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM