为什么该组通过使SQL查询更快

时间:2010-12-07 04:39:14

标签: sql sql-server-2008 query-optimization

以下两个查询给出了相同的结果,但使用group by的查询运行速度更快。这是否表明优化的查询有利于尽可能使用group?或者我更有可能遇到某种特殊情况?

更快的查询(对我来说不那么直观):

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

3 个答案:

答案 0 :(得分:1)

根据您的评论,您希望广告客户同时拥有NULL和最终状态。

这应该会产生预期的结果。 DISTINCT通常意味着“我正在重复......不确定为什么”,通常它会隐藏一个粉丝陷阱。在这种情况下,您可能有一个'final'的笛卡尔积和每个广告商的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

2个聚合的INNER JOIN:

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

另一个想法是使用CASE并使用单个GROUP BY / HAVING计算NULL和FINALS

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)

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

答案 1 :(得分: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。它与使用子查询几乎相同,除非它是物化视图。

答案 2 :(得分:0)

如果在两个查询中都删除了最外层的组,您是否看到返回的行数不同?这可能解释了它。