как оптимизировать мой SQL-запрос - PullRequest
2 голосов
/ 22 сентября 2011

Я хочу оптимизировать свой SQL-запрос, который я написал ранее (см. Ниже прикрепленный SQL-запрос).Этот запрос прост и очень прост, но его необходимо изменить, так как он не проходит тест производительности, и я знаю, что запрос медленный.Мой руководитель команды упомянул мне, что в запросе нужно использовать «Pivoting», но я не понял, как это сделать.Пожалуйста, кто-нибудь может помочь мне в этом.

Declare @tempTable Table(
DataSourceColumID int, fDataSourceID int, seqNum int, ColName varchar(50), HeaderName varchar(50)
)
Insert into @tempTable 
(DataSourceColumID, fDataSourceID,seqNum, ColName,HeaderName) 
Select 101,1,2,'col1', 'column 1'
Union ALL
Select 102,1,1,'col2', 'column 2'
Union All
Select 103,1,3,'col6', 'column 6'
Union All
Select 104,1,4,'col50', 'column 50'
select * From @tempTable 

Declare @ColumnOrderTable table (col_A varchar(10),col_B varchar(10),col_C varchar(10),col_D varchar(10),col_E varchar(10),col_F varchar(10),col_G varchar(10))
Insert into @ColumnOrderTable (col_A ,col_B ,col_C ,col_D ,col_E ,col_F ,col_G )
select 
Case When seqNum=1 then HeaderName else '' end as col_A,
Case When seqNum=2 then HeaderName else '' end as col_B ,
Case When seqNum=3 then HeaderName else '' end as col_C ,
Case When seqNum=4 then HeaderName else '' end as col_D ,
Case When seqNum=5 then HeaderName else '' end as col_E ,
Case When seqNum=6 then HeaderName else '' end as col_F, 
Case When seqNum=7 then HeaderName else '' end as col_G
from @tempTable

select max(col_A) as col_A ,max(col_B) col_B,max(col_C) col_C,max(col_D) col_D,max(col_E) col_E,max(col_F) col_F,max(col_G) col_G  From @ColumnOrderTable 

Ответы [ 2 ]

3 голосов
/ 22 сентября 2011

Вместо выбора в @ColumnOrderTable вы можете пропустить этот шаг и использовать подвыбор.

Упрощенный исходный оператор

SELECT  MAX(col_A)
        , MAX(col_B)
        , MAX(col_C)
        , MAX(col_D)
        , MAX(col_E)
        , MAX(col_F)
        , MAX(col_G)
FROM    (
          SELECT
            Case When seqNum=1 then HeaderName else '' end as col_A,
            Case When seqNum=2 then HeaderName else '' end as col_B ,
            Case When seqNum=3 then HeaderName else '' end as col_C ,
            Case When seqNum=4 then HeaderName else '' end as col_D ,
            Case When seqNum=5 then HeaderName else '' end as col_E ,
            Case When seqNum=6 then HeaderName else '' end as col_F, 
            Case When seqNum=7 then HeaderName else '' end as col_G
          FROM  @tempTable
        ) t

Сам подвыбор можно опустить, преобразовав этот оператор с помощьюфункция PIVOT .

Использование PIVOT

SELECT  col_A = [1]
        , col_B = [2]
        , col_C = [3]
        , col_D = [4]
        , col_E = [5] 
        , col_F = [6]
        , col_G = [7]
FROM    (SELECT seqNum, HeaderName FROM @tempTable) t
PIVOT   (MAX(HeaderName) FOR seqNum IN ([1], [2], [3], [4], [5], [6], [7])) pt  
2 голосов
/ 22 сентября 2011

Ваш подход отстой во многих отношениях:

  • Сначала вы делаете выбор во временную таблицу.Это означает, что все данные должны быть скопированы до остановки второго шага.
  • Затем вы снова копируете в другую временную таблицу
  • И, наконец, вы делаете максимум.

Это новичок nonono.

  • Ликвидация ОБА временных таблиц.Просто избавься от них.Даже без использования разворота или чего-то в этом просто нет необходимости.Вы можете выбрать (max) непосредственно при проходе через SQL.Временные таблицы ПЛОХО, поскольку они означают, что ВСЕ данные должны быть обработаны в первую очередь - в вашем случае вы обрабатываете все данные ТРИ РАЗ.Оптимизатор не может оптимизировать это.

Во-вторых, проверьте Pivot.Документация есть;) Посмотри, вернись с конкретными вопросами.

...