2010-12-07 51 views
0

以下兩個查詢給了我相同的結果,但使用group by運行速度更快。這是否表明優化查詢將有利於在可能的情況下使用組?或者更可能是我遇到某種特殊情況?爲什麼羣組通過使sql查詢速度如此之快

更快的查詢(不太直觀我):

SELECT  A.Advertiser 
FROM   (SELECT  TOP (100) PERCENT Advertiser, [Final Status] 
         FROM   dbo.Rehenas_View_2 
         GROUP BY [Final Status], Advertiser 
         HAVING  ([Final Status] IS NULL)) AS A INNER JOIN 
          (SELECT  TOP (100) PERCENT Advertiser, [Final Status] 
          FROM   dbo.Rehenas_View_2 AS Rehenas_View_2_1 
          GROUP BY [Final Status], Advertiser 
          HAVING  ([Final Status] = N'final')) AS B ON A.Advertiser = B.Advertiser 
GROUP BY A.Advertiser 

慢查詢(我正在努力簡化以上時,我注意到了速度差)

SELECT  A.Advertiser 
FROM   (SELECT  TOP (100) PERCENT Advertiser, [Final Status] 
         FROM   dbo.Rehenas_View_2 
         WHERE  ([Final Status] IS NULL)) AS A INNER JOIN 
          (SELECT  TOP (100) PERCENT Advertiser, [Final Status] 
          FROM   dbo.Rehenas_View_2 AS Rehenas_View_2_1 
          WHERE  ([Final Status] = N'final')) AS B ON A.Advertiser = B.Advertiser 
GROUP BY A.Advertiser 
+0

也許在兩者上運行EXPLAIN PLAN都會給你一個提示。 – duffymo 2010-12-07 04:44:47

+1

性能將取決於這是哪個數據庫。當然看起來是MSSQL,但你應該用一個標籤明確地聲明它。 – 2010-12-07 04:50:05

回答

0

兩個查詢似乎要複雜得多。難道他們不會給出與此相同的結果嗎?

SELECT Advertiser 
FROM   dbo.Rehenas_View_2 
WHERE [Final Status] IS NULL 

UNION 

SELECT Advertiser 
FROM dbo.Rehenas_View_2 
WHERE [Final Status] = N'final' 

這應該也快很多。

當然,無論何時從視圖中進行選擇,都無法查看查詢本身,也必須查看視圖sql。這與使用子查詢幾乎相同,除非它是物化視圖。

0

如果在兩個查詢中消除最外面的組,您是否看到返回行數的差異?這可能可以解釋它。

1

根據您的意見,您希望廣告客戶同時具有NULL和最終狀態。

這應該呈現所需的結果。 DISTINCT通常意味着「我得到重複...不知道爲什麼」,通常它隱藏了一個迷你陷阱。在這種情況下,每個廣告客戶可能會有'最終'和NULL行的笛卡爾積。

SELECT DISTINCT A.Advertiser 
FROM dbo.Rehenas_View_2 AS A, 
     dbo.Rehenas_View_2 AS B 
WHERE A.[Final Status] IS NULL 
    AND B.[Final Status] = N'final' 
    AND A.Advertiser = B.Advertiser 

INNER JOIN的2個骨料:

SELECT Advertiser FROM 
( SELECT Advertiser, COUNT(1) AS StatusCount 
    FROM dbo.Rehenas_View_2 WHERE [Final Status] IS NULL 
    GROUP BY Advertiser 
    HAVING StatusCount > 0) AS N, 
(
    SELECT Advertiser, COUNT(1) AS StatusCount 
    FROM dbo.Rehenas_View_2 WHERE [Final Status] = N'final' 
    GROUP BY Advertiser 
    HAVING StatusCount > 0) AS F 
WHERE N.Advertiser = F.Advertiser 

另一個想法是用例和統計NULL和決賽用單GROUP BY/HAVING

SELECT Advertiser FROM 
( SELECT Advertiser, 
     SUM(CASE WHEN [Final Status] IS NULL THEN 1 ELSE 0 END) AS NullCount, 
     SUM(CASE WHEN [Final Status] = N'final' THEN 1 ELSE 0 END) AS FinalCount 
    FROM dbo.Rehenas_View_2 WHERE [Final Status] IS NULL 
    GROUP BY Advertiser 
    HAVING NullCount > 0 AND FinalCount > 0) 

我沒有測試此語法的環境。

相關問題