在某些情况下,我们在SSRS报告的过滤器中使用IN子句。通过在IN子句中使用数百个项目,其中许多都会导致性能问题。 如:
WHERE TableA.School IN (@School)
有时,多值参数处理起来非常棘手,您可能需要在RDL中执行= Join(Mypara.Value,“,”)并编写一个SQL函数将它们转换为一组SQL数据能够提供SQL SP。 (特别是一些旧版本的SSRS)。
FYI:用于将逗号分隔符字符串分解为记录集的函数:
CREATE function [dbo].[fnSpark_BreakUpList] (
@List VARCHAR(MAX)
)
RETURNS @csvlist TABLE (Item VARCHAR(MAX))
AS
BEGIN
DECLARE @Item VARCHAR(MAX)
-- Loop through each item in the comma delimited list
WHILE (LEN(@List) > 0)
BEGIN
IF CHARINDEX(',',@list) > 0
BEGIN
SET @Item = SUBSTRING(@List,1,(CHARINDEX(',', @List)-1))
SET @List = SUBSTRING(@List,(CHARINDEX(',', @List) + DATALENGTH(',')),DATALENGTH(@List))
END
ELSE
BEGIN
SET @Item = @List
SET @List = NULL
END
-- Insert each item into the csvlist table
INSERT into @csvlist (Item) VALUES (@Item)
END
RETURN
END
GO
我将在短期内发布答案,以展示如何使用CHARINDEX提高性能。 (所以你不需要像上面那样......)
答案 0 :(得分:0)
如果您实际上并不想从LONG分隔字符串中检索项目,而只想过滤它,那么CHARINDEX是一种更好的方法。
您可以使用:
,而不是使用IN ClauseWHERE CHARINDEX(','+TableA.School+',',','+@School+',') > 0
注意: 1.我在目标字符串的末尾添加一个额外的逗号' TableA.School'避免如果大字符串包含与过滤项目相同的子字符串的饱和度。 (例如我们有一所名为' AB'以及另一个' ABC'我们不希望在我们针对&#时选择' ABC' 39; AB' ....)
我在资源字符串的末尾添加了一个额外的逗号' @ School'确保单个项目/最后一个项目(它们将以逗号结尾)在我们定位时将被选中。
我在目标字符串的开头添加一个额外的逗号' TableA.School'避免如果大字符串包含与过滤项目相同的子字符串的饱和度。 (例如我们有一所名为' AB'以及另一个' CAB'我们不希望在我们针对&#时选择' CAB' 39; AB' ....)
示例:
我正在使用:
WHERE
CHARINDEX(','+CAST(DENTIST4.wStudentYear AS VARCHAR(10))+',',','+@StudentYear+',') > 0
替换:
WHERE
DENTIST4.wStudentYear IN (@StudentYear)
对于我正在做的一个报告,这使得4000多页的渲染率从大约10分钟提高到大型数据库(11 G)的最小值。
重要说明: 请确保传入数据集的过滤器报告参数使用JOIN子句。
=Join(Parameters!MyParameter.Value,",")
希望这会有所帮助......
重要提示:如果过滤器具有大量项目,则此方法仅提高性能,对于具有少量项目的任何过滤器,IN子句将执行更好的工作。