2011-03-30 35 views
3

的我有兩個大表如何避免GROUP BY上很多列

- 主表答:1.4million行
-detail B表:9個百萬行

B有一個外鍵A.

基本上我需要所有25個從表A +細節字段在這種情況下對B.

計數

現在我有以下僞查詢:

Select 
     A.field1, 
     A.field2, 
     ... 
     A.field25, 
     Count(b.id) 
from 
     A left outer join B on B.fkAid = A.id 
Group by 
     A.id, 
     A.field1, 
     A.field2, 
     ... 
     A.field25 
Order by A.field1 

Query計劃顯示分組需要很多時間(並不令人意外)。

有沒有更有效的方法來做這種選擇?

+0

你有什麼指標? – 2011-03-30 13:10:32

+0

B上的聚簇索引(fkAid,B.id)和A上的PK – Pleun 2011-03-30 13:11:09

+0

「GROUP BY」列表包含A上的PK嗎?不清楚你的問題。如果是這樣,向組添加額外的表A列可能很乏味,但不應該影響查詢計劃。 – 2011-03-30 13:24:25

回答

3

有關使用公用表表達式是什麼(你標記它的SQL Server 2008?)

WITH CountB AS 
(
    SELECT A.aId, value= Count(*) 
    FROM A left outer join B on B.fkAid = A.id 
    GROUP BY A.id 
) 
Select 
    A.field1, 
    A.field2, 
    ... 
    A.field25, 
    CountB.value 
from 
    A left outer join CountB on A.id = CountB.aId 
Order by A.field1 
+0

似乎快了50%以上。謝謝你的幫助。 – Pleun 2011-03-30 14:01:57

+0

@Pleun - 有趣的是知道爲什麼。到目前爲止,我所做的每個實驗都有這個版本以更高的成本出現。 – 2011-03-30 14:39:10

2

你可能會與相關子查詢嘗試 - 但它可能是效率更低:

Select 
     A.field1, 
     A.field2, 
     ... 
     A.field25, 
     (select Count(*) from B where B.fkAid = A.id) 
from 
     A 
Order by A.field1 

其實我想到左連接和分組更有效的,如果沒有WHERE子句,除非列在表A中非常廣泛。其他

一種可能性是:

Select 
     A.field1, 
     A.field2, 
     ... 
     A.field25, 
     Coalesce(b.Cnt,0) 
from 
     A left join 
     (select fkAid,COUNT(*) from B group by fkAId) b (ID,Cnt) 
     on A.ID = b.ID 
Order by A.field1 

,這可能是最好的參與沒有where子句。

+1

「但它可能效率更低: 」 - 不確定這是多麼有用! – 2011-03-30 13:11:36

+1

@Mitch - 這是你必須嘗試每種組合,並根據你的實際數據看看哪個最好的方法之一 - 我不是一個說「像從未做X」這樣的專制主義者 - 我喜歡給人們選擇。 OP已表示他們已經能夠檢查計劃。 – 2011-03-30 13:13:31

+0

在黑暗中刺傷有時是有效的;我更喜歡具體的方法。 – 2011-03-30 13:15:36

0

您可以嘗試使用OUTER APPLY

Select 
     A.field1, 
     A.field2, 
     ... 
     A.field25, 
     C.Quant 
from 
     A OUTER APPLY (SELECT COUNT(*) Quant FROM B WHERE A.id = B.fkAid) AS C 
Order by A.field1