2013-06-22 45 views
0

我給我在這裏執行查詢的一部分:奇怪的執行時間彙總查詢

SELECT SUM(ParentTable.Field1), 
     (SELECT SUM(ChildrenTable.Field1) 
     FROM ChildrenRable INNER JOIN 
      GrandChildrenTable ON ChildrenTable.Id = GrandChildrenTable.ChildrenTableId INNER JOIN 
      AnotherTable ON GrandChildrenTable.AnotherTableId = AnotherTable.Id 
     WHERE ChildrenTable.ParentBaleId = ParentTable.Id 
     AND AnotherTable.Type=1), 
     ---- 
FROM ParentTable 
WHERE some_conditions 

關係:

ParentTable -> ChildrenTable = 1-to-many 
ChildrenTable -> GrandChildrenTable = 1-to-many 
GrandChildrenTable -> AnotherTable = 1-to-1 

我執行這個查詢三次,而只改變類型條件,這裏是結果:

返回的記錄數:

Condition Total execution time (ms) 
Type = 1 :   973 
Type = 2 :   78810 
Type = 3 :   648318 

如果我只執行內部聯接查詢,這裏是加入記錄的計數:

SELECT p.Type, COUNT(*) 
FROM CycleActivities ca INNER JOIN 
    CycleActivityProducts cap ON ca.Id = CAP.CycleActivityId INNER JOIN 
Products p ON cap.ProductId = p.Id 
GROUP BY p.Type 

Type 
---- ----------- 
1  55152 
2  13401 
4 102730 

那麼,爲什麼會與類型= 1分的條件查詢執行速度遠遠超過同類型= 2的查詢,儘管它查詢的是4倍大的結果集(Type是tinyint)?

回答

0

查詢寫入的方式指示SQL Server對輸出的每一行執行JOIN的子查詢。

這樣,它應該會更快,如果我理解你想要什麼正確(修訂版):

with cte_parent as (
    select 
     Id, 
     SUM (ParentTable.Field1) as Parent_Sum 
from ParentTable 
group by Id 
), 

cte_child as (
    SELECT 
     Id, 
     SUM (ChildrenTable.Field1) as as Child_Sum 
    FROM ChildrenRable 
     INNER JOIN 
      GrandChildrenTable ON ChildrenTable.Id = GrandChildrenTable.ChildrenTableId 
     INNER JOIN 
      AnotherTable ON GrandChildrenTable.AnotherTableId = AnotherTable.Id 
    WHERE 
      AnotherTable.Type=1 
     AND 
      some_conditions 
    GROUP BY Id 
) 

select cte_parent.id, Parent_Sum, Child_Sum 
from parent_cte 
join child_cte on parent_cte.id = child_cte.id 
+0

嗨Stoleg,你不能組在ParentTable.Field1這樣的,因爲這將成倍根據該結果加入記錄的數量。這同樣適用於SUM(ChildrenTable.Field1)。唯一能夠正確工作的是如果你做了一個SUM(GrandChildrenTable.Field1)。 – Goran

+0

我的猜測是你對輸出中的多行感興趣,對吧?輸出的每一行將是一個(簡單情況下)屬性的摘要。你需要的數字的總和是多少?或者你只需​​要一行中的所有數據? – Stoleg

+0

我感興趣的並不重要因爲你寫的查詢在任何情況下都是不正確的,讓我更精確一點:假設你在ParentTable中有1條記錄,ParentTable.field1 = 200,並且你在ChildrenTable中有兩條記錄,每條記錄有一條引用記錄在GrandChildren表中執行查詢時,SUM(ParentTbale.Field1)將返回2x200 = 400,而不是200,這是不正確的。 – Goran