2012-03-09 97 views
0

我一直在這一塊上撞了我一會兒。我想實現這一點:Linq2SQL group-by和總和優化

SELECT [t2].[nArtKey], [t2].[value] AS [nQty] 
FROM (
    SELECT SUM([t0].[nQty]) AS [value], [t1].[nArtKey] 
     FROM [vdatStockTransactions] AS [t0] 
     INNER JOIN [regArtSKU] AS [t1] ON [t0].[nSKU] = [t1].[nSKU] 
     GROUP BY [t1].[nArtKey] 
     ) AS [t2] 
    INNER JOIN [regArticles] AS [t3] ON [t2].[nArtKey] = [t3].[nArtKey] 
    INNER JOIN [regGroupConnector] AS [t4] ON [t2].[nArtKey] = [t4].[nArtKey] 
WHERE [t2].[value] > @p0 

我到目前爲止使用LINQ讓我幾乎正是我想要的,exept的數量...

from trans in context.vdatStockTransactions 
join sku in context.regArtSKUs on trans.nSKU equals sku.nSKU 
group trans by new { sku.nArtKey } into grp 
where grp.Sum(g => g.nQty) > 0 
join art in context.regArticles on grp.Key.nArtKey equals art.nArtKey  
join ca in context.regGroupConnectors on grp.Key.nArtKey equals ca.nArtKey 
select new 
{ 
    nArtKey = grp.Key.nArtKey, 
    //nQty = grp.Sum(g => g.nQty) 
}; 

但是,如果我去掉nQty我得到這個:

SELECT [t7].[nArtKey], [t7].[value] AS [nQty] 
FROM (
    SELECT [t3].[nArtKey], (
     SELECT SUM([t5].[nQty]) 
     FROM [vdatStockTransactions] AS [t5] 
     INNER JOIN [regArtSKU] AS [t6] ON [t5].[nSKU] = [t6].[nSKU] 
     WHERE [t2].[nArtKey] = [t6].[nArtKey] 
     ) AS [value], [t2].[value] AS [value2] 
    FROM (
     SELECT SUM([t0].[nQty]) AS [value], [t1].[nArtKey] 
     FROM [vdatStockTransactions] AS [t0] 
     INNER JOIN [regArtSKU] AS [t1] ON [t0].[nSKU] = [t1].[nSKU] 
     GROUP BY [t1].[nArtKey] 
     ) AS [t2] 
    INNER JOIN [regArticles] AS [t3] ON [t2].[nArtKey] = [t3].[nArtKey] 
    INNER JOIN [regGroupConnector] AS [t4] ON [t2].[nArtKey] = [t4].[nArtKey] 
    ) AS [t7] 
WHERE [t7].[value2] > @p0 

爲什麼它創建額外的子查詢,有什麼辦法可以避免它?它在性能上有很大的差異,所以我真的很想弄明白這一點。我只需要使用數量([t2]。[value])並將其存入SELECT語句中。

只有在羣組之後有多個連接時,纔會存在額外的子查詢,因此如果我刪除或者查詢生成預期的SQL。

注:我將原始查詢分解爲只保留正在生成此行爲的零件,以便更容易遵循。

回答

0

我沒有測試過這一點,但是這可能做的伎倆:

var quantities = 
    from trans in context.vdatStockTransactions 
    group trans by trans.SKU.nArtKey into grp 
    select new 
    { 
     nQty = grp.Sum(g => g.nQty), 
     nArtKey = grp.Key 
    }; 

var results = 
    from quantity in quantities 
    join art in context.regArticles 
     on quantity.nArtKey equals art.nArtKey  
    join ca in context.regGroupConnectors 
     on quantity.nArtKey equals ca.nArtKey 
    where quantity.nQty > 0 
    select quantity; 
+0

這奏效了!我只需在你的示例中添加連接到regArtSKU,它創造了奇蹟:)在使用你的建議修改了我的原始查詢之後,與之前的版本相比,在快速測試中性能提高了約45%。謝謝! :) – 2012-03-09 10:16:50

+0

不客氣。別忘了在查詢上運行SQL Server Index Tuning Wizzard可以創造奇蹟。 – Steven 2012-03-09 10:29:30