2014-11-14 8 views
2

Я пытаюсь выяснить, какой путь более эффективен. Я попытался использовать Sql Fiddle, но, похоже, он не распознал PIVOT или UNION. Какие инструменты или статистика можно посмотреть, чтобы определить, какая из них эффективнее.Pivot vs Case T-sql efficiency

CREATE TABLE T 
(
    PersonNum INT 
,WeekOf DATETIME 
,ActivityType1 INT 
,ActivityType2 INT 
,Hours INT 
) 

INSERT INTO T VALUES(1,'11/2/2014',5,0,40) 
INSERT INTO T VALUES(1,'11/2/2014',1,0,5) 
INSERT INTO T VALUES(1,'11/2/2014',1,0,8) 
INSERT INTO T VALUES(1,'11/2/2014',2,1,6) 
INSERT INTO T VALUES(1,'11/2/2014',2,2,2) 
INSERT INTO T VALUES(1,'11/2/2014',2,3,9) 
INSERT INTO T VALUES(1,'11/2/2014',2,4,7) 

INSERT INTO T VALUES(1,'11/9/2014',5,0,40) 
INSERT INTO T VALUES(1,'11/9/2014',1,0,2) 
INSERT INTO T VALUES(1,'11/9/2014',1,0,6) 
INSERT INTO T VALUES(1,'11/9/2014',2,1,7) 
INSERT INTO T VALUES(1,'11/9/2014',2,2,2) 
INSERT INTO T VALUES(1,'11/9/2014',2,3,3) 
INSERT INTO T VALUES(1,'11/9/2014',2,4,5) 

Метод 1

SELECT 
    PersonNum 
, WeekOf 
, SUM(CASE WHEN ActivityType1 = 5 THEN Hours ELSE 0 END) AS Beginning 
, SUM(CASE WHEN ActivityType1 = 1 THEN Hours ELSE 0 END) AS Plus 
, SUM(CASE WHEN ActivityType1 = 2 AND ActivityType2 <> 3 THEN Hours ELSE 0 END) AS Minus 
, SUM(CASE WHEN ActivityType1 = 2 AND ActivityType2 = 3 THEN Hours ELSE 0 END) AS MinusSpecial 
FROM T 
GROUP BY 
    PersonNum 
, WeekOf 

Метод 2

SELECT 
    PersonNum 
, WeekOf 
, [Beginning] 
, [Plus] 
, [Minus] 
, [Minus Special] 
FROM 
(
    SELECT 
    PersonNum 
    , WeekOf 
    , 'Beginning' AS ColumnType 
    , Hours 
    FROM T 
    WHERE 
    ActivityType1 = 5 
    UNION 
    SELECT 
    PersonNum 
    , WeekOf 
    , 'Plus' AS ColumnType 
    , Hours 
    FROM T 
    WHERE 
    ActivityType1 = 1 
    UNION 
    SELECT 
    PersonNum 
    , WeekOf 
    , 'Minus' AS ColumnType 
    , Hours 
    FROM T 
    WHERE 
     ActivityType1 = 2 
    AND ActivityType2 <> 3 
    UNION 
    SELECT 
    PersonNum 
    , WeekOf 
    , 'Minus Special' AS ColumnType 
    , Hours 
    FROM T 
    WHERE 
     ActivityType1 = 2 
    AND ActivityType2 = 3 
    ) Data 
PIVOT 
(SUM(Hours) 
FOR ColumnType IN ([Beginning]     
        ,[Plus] 
        ,[Minus] 
        ,[Minus Special]) 
) pvt 
+1

Взгляните на эту статью. Он охватывает различные способы выполнения этого типа запросов и исследует производительность. http://www.sqlservercentral.com/articles/T-SQL/63681/ –

ответ

1

Вы можете сделать это

set statistics time on 

--first query 

set statistics time off 

set statistics time on 

--second query 

set statistics time off 

Вы можете посмотреть в окне сообщений, чтобы увидеть время выполнения

+0

Ничего себе, стержень примерно в 3,5 раза медленнее – Mike

1

Метод 1 будет быстрее. Это связано с тем, что существует только один оператор select. С другой стороны в методе 2 есть 5 операторов select. Общее правило состоит в том, что в запросе большего числа запросов содержится больше времени, которое требуется выполнить.

5

Позвольте мне предложить переписать ваш запрос PIVOT, чтобы вам не приходилось ударять по таблице 5 раз.

select P.PersonNum, 
     P.WeekOf, 
     P.Beginning, 
     P.Plus, 
     P.Minus, 
     P.MinusSpecial 
from (
    select T.PersonNum, 
      T.WeekOf, 
      T.Hours, 
      case ActivityType1 
      when 5 then 'Beginning' 
      when 1 then 'Plus' 
      when 2 then case ActivityType2 
          when 3 then 'MinusSpecial' 
          else 'Minus' 
         end 
      end as ColumnType 
    from T 
    ) as T 
pivot (sum(T.Hours) for T.ColumnType in (Beginning, Plus, MinusSpecial, Minus)) as P 

С этим вы, вероятно, получите тот же план запросов, что и ваша группа, по запросу и примерно с той же производительностью.