почему группа делает SQL-запрос намного быстрее - PullRequest
0 голосов
/ 07 декабря 2010

Следующие два запроса дают мне тот же результат, но тот, который использует group by, выполняется быстрее. Означает ли это, что оптимизированные запросы предпочтут использовать group by, когда это возможно? Или более вероятно, что я переживаю какой-то особый случай?

более быстрый запрос (менее интуитивный для меня):

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 ]

1 голос
/ 07 декабря 2010

Согласно вашим комментариям вы хотели бы, чтобы рекламодатели имели как 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 агрегатов:

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 и считать NULL и FINALS с одной 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)

У меня нет среды для проверки этого синтаксиса.

0 голосов
/ 07 декабря 2010

Если вы исключите самую внешнюю группу в обоих запросах, увидите ли вы разницу в количестве возвращаемых строк?Это может объяснить это.

0 голосов
/ 07 декабря 2010

Оба запроса кажутся намного более сложными.Разве они не дают такой же результат, как этот?

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.Это почти то же самое, что и использование подзапроса, за исключением случаев, когда это материализованное представление.

...