2015-06-27 45 views
0

我正在調整一些聚合重度查詢的性能,我想知道重複相同的聚合函數是否會有顯着的性能損失。MS SQL Server是否在單個查詢中合併重複的聚合?

我假設MS SQL Server是足夠的智能來計算每個重複彙總一次,然後,準確的骨料在同一查詢中每次遇到重用得到的值 - 是我的假設是正確的嗎?

的替代,這是,我們可以在一羣不同的方式來產生各種添加一堆更聯接到該視圖(反覆接合相同的表再次),伴有不同join on條款,對行分組在一起總計而不是重複使用任何聚合函數 - 但看着執行計劃,我們可以看到明確添加更多連接確實使查詢花費更長時間,而且我們在技術上已經擁有了我們需要的所有信息以及當前的連接數(我們只需執行加法來產生複合總數)。

下面是一些示例代碼,從有問題的意見之一:

COUNT_BIG ([UVCE]. [ID]) AS [TotalU] , 
COUNT_BIG ([SVCE]. [ID]) AS [TotalS] , 
COUNT_BIG ([TVCE]. [ID]) AS [TotalT] , 
COUNT_BIG ([CVCE]. [ID]) AS [TotalC] , 
COUNT_BIG ([WVCE]. [ID]) AS [TotalW] , 
/* More individual totals, etc. */ 

COUNT_BIG ([SCE]. [ID]) + 
COUNT_BIG ([TCE]. [ID]) + 
COUNT_BIG ([CCE]. [ID]) + 
COUNT_BIG ([WCE]. [ID]) + 
COUNT_BIG ([UVCE]. [ID]) + 
COUNT_BIG ([SVCE]. [ID]) + 
COUNT_BIG ([TVCE]. [ID]) + 
COUNT_BIG ([CVCE]. [ID]) + 
COUNT_BIG ([WVCE]. [ID]) AS [OverallTotal] , 

CASE WHEN COUNT_BIG ([SCE]. [ID]) + 
      COUNT_BIG ([TCE]. [ID]) + 
      COUNT_BIG ([CCE]. [ID]) + 
      COUNT_BIG ([WCE]. [ID]) + 
      COUNT_BIG ([UVCE]. [ID]) + 
      COUNT_BIG ([SVCE]. [ID]) + 
      COUNT_BIG ([TVCE]. [ID]) + 
      COUNT_BIG ([CVCE]. [ID]) + 
      COUNT_BIG ([WVCE]. [ID]) >= 64 THEN 4E0 ELSE (
      COUNT_BIG ([SCE]. [ID]) + 
      COUNT_BIG ([TCE]. [ID]) + 
      COUNT_BIG ([CCE]. [ID]) + 
      COUNT_BIG ([WCE]. [ID]) + 
      COUNT_BIG ([UVCE]. [ID]) + 
      COUNT_BIG ([SVCE]. [ID]) + 
      COUNT_BIG ([TVCE]. [ID]) + 
      COUNT_BIG ([CVCE]. [ID]) + 
      COUNT_BIG ([WVCE]. [ID])) 
     /(64/4E0) END AS [Score] 
+2

你能計算一次,並在計數上做一個外部查詢來生成最終結果嗎? – Tim3880

+0

@ Tim3880這是一個很好的觀點,我想我可以 - 很好的解決方法。老實說,我可能會這樣做 - 使代碼不那麼醜陋。 – Giffyguy

+1

我總是想先獲得聚合結果。除此之外的任何事情都應該在很短的(通常是一行)結果上工作。它也爲您節省了一些打字時間。 – Tim3880

回答

1

SQL Server優化是相當不錯的。

但是,您在使用聚合函數時缺少重要的一點。一般而言,group by子句比聚合函數調用更昂貴。也就是說,移動數據來定義組是查詢的昂貴部分。 (一個例外是count(distinct)。)

這就是說,做幾十個函數調用可以有一個顯着的性能影響。在SQL Server中,很容易使用公用表表達式(CTE)或子查詢來定義一個級別的值並在另一個級別上使用它們。也就是說,SQL Server可能會爲你做這件事。我認爲查詢的其他部分可能在性能方面更重要。