如何优化我的SQL查询

时间:2011-09-22 04:00:10

标签: sql sql-server sql-server-2005 tsql reportingservices-2005

我想优化我之前编写的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 个答案:

答案 0 :(得分:3)

您可以省略该步骤并使用子选择,而不是选择@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  

答案 1 :(得分:2)

您的方法在很多方面都很糟糕:

  • 首先,您选择一个临时表。这意味着必须在第二步停止之前复制所有数据。
  • 然后再次复制到另一个临时表
  • 然后最后你做了最多。

这是一个非常初学者。

  • 消除两个临时表。摆脱它们。即使不使用枢轴或其他东西,也根本不需要。您可以直接在传递SQL上选择(max)。临时表是坏的,因为它们意味着必须首先处理所有数据 - 在您的情况下,您处理所有数据三次。优化器无法优化它。

其次,检查Pivot。有文档;)查阅,返回具体问题。