2016-07-26 74 views
2

我目前在MSSQL中有一个存储过程,根据我给存储过程的变量多次执行SELECT语句。存储过程计算用户可以启用的每个过滤器将返回多少结果。 存储过程不是问题,我从转化TE存储过程中的SELECT语句为常规的选择语句,它看起来像:更大的结果集的性能问题MSSQL

DECLARE @contentRootId int = 900589 
DECLARE @RealtorIdList varchar(2000) = ';880;884;1000;881;885;' 
DECLARE @publishSoldOrRentedSinceDate int = 8 
DECLARE @isForSale BIT= 1 
DECLARE @isForRent BIT= 0 
DECLARE @isResidential BIT= 1 
--...(another 55 variables)... 

--Table to be returned 
DECLARE @resultTable TABLE 
(
    variableName varchar(100), 
    [value] varchar(200) 
) 

-- Create table based of inputvariable. Example: turns ';18;118;' to a table containing two ints 18 AND 118 
DECLARE @RealtorIdTable table(RealtorId int) 
INSERT INTO @RealtorIdTable SELECT * FROM dbo.Split(@RealtorIdList,';') option (maxrecursion 150) 

INSERT INTO @resultTable ([value], variableName) 
SELECT [Value], VariableName FROM( 
    Select count(*) as TotalCount, 
     ISNULL(SUM(CASE WHEN reps.ForRecreation = 1 THEN 1 else 0 end), 0) as ForRecreation, 
     ISNULL(SUM(CASE WHEN reps.IsQualifiedForSeniors = 1 THEN 1 else 0 end), 0) as IsQualifiedForSeniors, 
     --...(A whole bunch more SUM(CASE)... 
    FROM TABLE1 reps 
    LEFT JOIN temp t on 
      t.ContentRootID = @contentRootId 
      AND t.RealEstatePropertyID = reps.ID 
     WHERE 
      (EXISTS(select 1 from @RealtorIdTable where RealtorId = reps.RealtorID)) 
      AND (@SelectedGroupIds IS NULL OR EXISTS(select 1 from @SelectedGroupIdtable where GroupId = t.RealEstatePropertyGroupID)) 
      AND (ISNULL(reps.IsForSale,0) = ISNULL(@isForSale,0)) 
      AND (ISNULL(reps.IsForRent, 0) = ISNULL(@isForRent,0)) 
      AND (ISNULL(reps.IsResidential, 0) = ISNULL(@isResidential,0)) 
      AND (ISNULL(reps.IsCommercial, 0) = ISNULL(@isCommercial,0)) 
      AND (ISNULL(reps.IsInvestment, 0) = ISNULL(@isInvestment,0)) 
      AND (ISNULL(reps.IsAgricultural, 0) = ISNULL(@isAgricultural,0)) 
      --...(Around 50 more of these WHERE-statements)... 
      ) as tbl 

    UNPIVOT ( 
     [Value] 
     FOR [VariableName] IN(
     [TotalCount], 
     [ForRecreation], 
     [IsQualifiedForSeniors], 
     --...(All the other things i selected in above query)... 
     ) 
    ) as d 

    select * from @resultTable 

一个Realtor-和内容识别的结合,给我的一组默认设置X数量的记录。当我选择组合给我〜4600条记录时,执行时间大约为250ms。当我用一个给我〜600条记录的组合执行sattement时,执行时间约为20ms。

我想知道为什么会发生这种情况。我尝试删除所有SUM(CASE中的select,我试着从WHERE子句中删除了几乎所有的东西,并且我尝试删除JOIN。但是我一直看到4600和600的结果集之间的巨大差异。

+0

检查参数嗅探并添加'OPTION(RECOMPILE)'。你也可以更新你的表上的统计。 se提供两种情况下的执行计划 – Devart

+0

我不确定你的意思是“你也可以更新你的表上的统计信息”。我尝试了参数嗅探,它有帮助,但不是很多。我会检查选项(RECOMPILE) – user2939331

+0

'ISNULL(reps.IsForSale,0)= ISNULL(@ isForSale,0)' - 这些'isnull's也是问题。你最好把它改写成'(@ isforsale is null或isforsale = @ isforsale)'+重新编译 –

回答

1

表变量如果记录数很大,可能会更糟糕,请考虑使用临时表,请参阅When should I use a table variable vs temporary table in sql server?

另外,请考虑使用替代SQL代码替换UNPIVOT,编写自己的TSQL代码将为您提供更多的控制权,甚至可以提高性能。看例如PIVOT, UNPIVOT and performance

+0

我已经尝试删除硬数据的所有表,但如果我这样做,查询速度并不会更快。 – user2939331

+0

在执行查询并上传输出之前,您是否可以执行SET STATISTICS TIME,IO ON?这会让我们了解性能问题来自哪里。 –

+0

http://codepaste.net/efxenf这是“消息”中显示的结果 – user2939331