2010-08-13 174 views
0

我知道所有的域聚合函數都很慢,但我正在尋找最少的問題。查詢或dsum MS Access性能查詢?

下面兩個選項中哪個更快?

  1. 創建一個查詢,該查詢將按唯一值進行分組並總和。有dlookup從查詢中獲得我的總和。
  2. 在主表上做一個dsum,其標準與我在選項1中的GROUP BY列相同?

編輯1
我的問題是,我在很多場合都知道一個普通的問題,但下面是正在考慮具體的情況現在。

在我的時間輸入詳細子表單上,我需要顯示此作業中使用了多少材料。對於文本框控件來源是這樣的:

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

tm_materialsUsedByPart目前正在總結中使用的所有材料的查詢。

使用具有本質上相同標準的dsum會更快嗎?還是更快地執行查詢,然後獲取符合我的標準的單行?

+0

添加了示例.. – Icode4food 2010-08-13 15:26:37

回答

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

沒有看到tm_materialsUsedByPart的SQL,我們只能猜測它在做什麼。也許它會讀取整個表格或一組JOIN表格,並使用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慢顯着

+0

因此,即使我目前正在使用索引,MS Access的智能性還不足以使用索引? [部分]被索引。另外,你對'tm_materialsUsedByPart'查詢做了什麼很好的觀點,它正在做一個JOIN。 – Icode4food 2010-08-13 15:53:09

+1

我喜歡@Thomas的建議,將總數包含在表單的記錄源中,只要記錄源可以是隻讀的,我就會這樣做。如果您需要編輯時間條目明細子表單中的記錄源值,請使用DSum()。 – HansUp 2010-08-13 16:05:26

+0

訪問不會執行任何操作。但是Jet/ACE數據庫引擎的確如此。如果您想了解如何優化查詢,那麼可以使用Google SHOWPLAN,但這無助於弄清楚域聚合函數的工作方式。通常,Jet/ACE(和域聚合函數)將使用所有索引,但有一些例外(例如,不用於子查詢,有時僅在比較的一側使用索引)。 – 2010-08-14 03:53:00

1

還有兩個選項:相關子查詢或派生表。相關子查詢將帶來宣佈在查詢到自己的列是一個查詢:

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

派生表,在Access中,將涉及創建保存的查詢做所有的總數,然後加入該查詢到你的主查詢。儘管可以在主查詢中快速構建總計查詢,但我的經驗是,Access對保存的查詢和標準連接更加滿意。如果您向我們展示更多關於您想要完成的內容,您可能會得到一些更具體的答案。

EDIT

IMO,最快的解決方案將是包括總,通過已保存的查詢,在源的形式。即,不使用DLookup或DSum,而是通過加入計算總計的查詢來將總數作爲表單的RecordSource的一部分。其次,要真正知道哪個函數的性能最好,您需要對數據進行一些性能測試。我的猜測是兩者之間的表現會相當。即使DLookup針對存儲的查詢,Access也應該足夠智能,以注入過濾標準,並實際上獲得使用DSum的類似執行計劃。

最後,如果您要使用域聚合函數,並且在DLookup中使用的查詢的唯一目的是爲此表單提供總計值,那麼IMO會使用DSum更有意義,因爲它會使您的意圖變爲域聚合函數的使用更清晰的讀者。

+0

我添加了編輯1.希望這會讓我更清楚我在問什麼。 – Icode4food 2010-08-13 15:25:24

+0

我無法將該字段添加到表單的記錄源,因爲表單數據需要可編輯。在記錄源中有一個GROUP BY查詢將不允許數據是可編輯的。 – Icode4food 2010-08-13 15:55:52

+1

@jeffreymb - 你不需要在記錄源中的一個組。如果您使用已保存的查詢,則只有已保存的查詢將具有該組。主查詢不會。如果您在記錄源中使用相關子查詢,則只有它具有一組而不是主查詢。 – Thomas 2010-08-13 17:05:03