2010-12-07 53 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) 

我没有测试此语法的环境。

相关问题