2016-07-26 40 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